utterlyconfused has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perlmonks,

Below is a code i'm testing. I am a beginner at Perl and saw that the $` special variable refers to the string preceding a match. I wanted to try using it to print a line previous to a matched string.
If this is not possible then any advice on how to print a string previous to a matched string would be very welcome. The problem is I get the following warning and can't figure out how to fix it

Use of uninitialized value in pattern match (m//) at test.pl line 9, <FH> line 1.
Use of uninitialized value in pattern match (m//) at test.pl line 9, <FH> line 2.
Use of uninitialized value in pattern match (m//) at test.pl line 9, <FH> line 3.
Use of uninitialized value in pattern match (m//) at test.pl line 9, <FH> line 4.
Use of uninitialized value in pattern match (m//) at test.pl line 9, <FH> line 5.

the contents of the file are (i'm only using this file to test the script, normally these files could have several strings of letters with each having a title line beginning with >)

>random_seq
atggtccgtgatcagcatcctttggggaatccacatttattcggaccacctccggattcgtcagcatgac +agctggtcgugguuuaguaugatgtgatgcgatcatgtacatcaggatttaggaggccctccactgcat +cgtcgactagacgatcagttagggaaaacgtaugguugugatggtacatgacggaccacacgccgactt +agcatttgttacagtagcgtgattgacatguuguuggug


I want to test the string of letters for a motif and if found print the line beginning with '>' (i.e. the line/string before the match). finally, here's the code


<code> #!usr/bin/perl use strict;use warnings;

my $filename = $ARGV[0];
open (FH, $filename) || die "Cannot open file\n";

while (<FH>)
{
if (my $line =~ m/A-Za-z/)
{
print $`;
}
}
close FH;
<code>
would appreciate any help you have to offer

GrandFather added code tags to break long line.

Replies are listed 'Best First'.
Re: Special Variable help
by andmott (Acolyte) on Jan 09, 2011 at 20:16 UTC

    It looks like you never assigned $line to anything, and are searching its contents, which are undefined. You may be getting confused about how Perl's default $_ is used in pattern matching. The program would do what you want if you left off the variable my $line and changed the if statement to read:

    if ( /A-Za-z/ )

    ... since $_ has the line data in it, not $line. Or conversely you could put the line data into the variable like this...

    while( my $line = <FH> ) { if ( $line =~ m/A-Za-z/ ) { .... } } close FH
Re: Special Variable help
by AnomalousMonk (Archbishop) on Jan 09, 2011 at 20:43 UTC

    The
        while (<FH>) { ... }
    construct reads by default to the special scalar variable $_ (dollar-underscore; see perlvar), but you are matching against the variable $line, which is never defined.

    Use of strictures and warnings is very wise, but not in the 'shebang' line, where they are ineffective: use them separately in the body of the script.

    Try something like the following (untested (Update: changed some variable names to be self-documenting)):

    #!usr/bin/perl use warnings; use strict; my $filename = $ARGV[0] or die "no file name given"; open my $fh, '<', $filename or die "opening '$filename': $!"; my $previous_line = ''; while (defined(my $current_line = <$fh>)) { chomp $current_line; if ($current_line =~ m{ \A [ACGTacgt]+ \z }xms) { print "$previous_line\n"; print "$current_line\n"; } $previous_line = $current_line; } close $fh or die "closing '$filename': $!";

    This will print every line that contains only base-pair letters, along with the line before it in the file. When this works, modify the
        m{ \A [ACGTacgt]+ \z }xms
    regex to match whatever a 'motif' is.

    Update: Since it looks like you're working with a FASTA-formatted file, check out the FASTA-related modules in CPAN; I'm not a bio-guy, so I can't advise which might be best for you.

Re: Special Variable help
by planetscape (Chancellor) on Jan 10, 2011 at 01:07 UTC