2

I have a signal file with each line beginning with 0 or 1.

If I have 1 followed by 0 in the next line, then I need to process the 0 signal line.

>#Sample File

>0

>0

>1

>0 (process line)

>0

>1

>0 (process line)
my code
 OUTER : while (<F>) {
   if($_=~/1/){
     my $a = <F>
     process_line($a) if ($a=~/0/);
     next OUTER if ($a=~/1/);
   }

The file is huge, so I don't want to slurp.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
made_in_india
  • 2,109
  • 5
  • 40
  • 63

3 Answers3

4

Something like:

#!/usr/bin/perl

use strict;
use warnings;
my $prevLine = "";

sub processline {
    my $line = shift;
    $line =~ s@^0 @@;
    print $line;
}

while (<DATA>) {
    if ($_ =~ /^0/ && $prevline =~ /^1/) {
        processline($_);
    }
    $prevLine = $_;
}

__DATA__
0
0
1
0 (process line)
0
1
0 (process line)

Output

(process line)
(process line)
  • Corrected the regexp, for/while and var case parts. Thanks for the clarifications. –  Nov 26 '11 at 16:35
1

I see the possible error with your code: Two or more consecutive lines starting with 1 will misfire and skip a match.

while (<>) {
   if(/^1/){            # Ignore everything except 1-lines
      while (<>) {      # Start inner loop
         next if /^1/;  # Skipping consecutive 1-lines
         die "Bad line: $_" unless /^0/;  # Anything not 1 or 0 is not allowed
         process_line($_);
         last;          # Exit inner loop, search for next 1-line
      }
   }
}

Usage options:

script.pl filename        (single file)
script.pl filename*       (glob, multiple files)
some_command | script.pl

Changes:

  • Global filehandle changed to diamond operator, works on STDIN or filename arguments to the script. If you want an explicit open, use open my $fh, '<', $filename or die $!
  • Added anchors in the regexes to match beginning of string only, e.g. /^1/
  • Removed unnecessary label OUTER. next and last will affect the innermost loop only (see perldoc -f last).
  • $_ =~ /^1/ changed to /^1/, which is equivalent, and more legible.
  • Nested use of $_ is valid, and will work as expected. If you want, the inner loop can use another variable, e.g. while (my $line = <>), which may be seem less confusing to some. (Not to me, though)

You should use strict and warnings, if you are not already doing so. Why use strict and warnings?

Community
  • 1
  • 1
TLP
  • 66,756
  • 10
  • 92
  • 149
0

Another variation:

#!/usr/bin/env perl
use strict;
use warnings;
sub processme {
    my $line = shift;
    print $line;
}
while (<>) {
    if (/^1/../^0/) {
        processme( $_ ) if /^0/;
    }
}
JRFerguson
  • 7,426
  • 2
  • 32
  • 36