in reply to How do I use grep in a script

Converting the steps from a shell pipeline to Perl is fairly easy. The steps are:

  1. grep Acct: Facs_Data.txt - Read a file line by line and select the lines matching Acct:
  2. cut -d":" -f2 - Take the side to the right of : of the line
  3. cut -d" " -f1 - take the side to the left of the blank of the line

If we convert each step to Perl, we get the following parts:

  1. my $filename = 'Facs_Data.txt'; open my $fh, '<', $filename or die "Couldn't open '$filename': $!"; my @lines = grep { /Acct:/ } <$fh>; # Read a file line by line and sel +ect the lines matching Acct:
  2. @lines = map { [ split $_, /:/ ]->[1] } @lines; # Take the side to the + right of : of the line
  3. @lines = map { [ split $_, /:/ ]->[0] } @lines; # take the side to the + left of the blank of the line

But a more perlish approach would be to do all that in one go:

my $filename = 'Facs_Data.txt'; open my $fh, '<', $filename or die "Couldn't open '$filename': $!"; my @lines = map { /:([^\s]+)/ ? $1 : () } # take the stuff between th +e : and the first blank grep { /Acct:/ } <$fh>; # Read a file line by line and sel +ect the lines matching Acct: # do whatever with the values in @lines print "$_\n" for @lines;

Update:: Fixed missing = in step three, spotted by AnomalousMonk, thanks.

Replies are listed 'Best First'.
Re^2: How do I use grep in a script
by ikegami (Patriarch) on Dec 26, 2017 at 17:35 UTC
    map { /:([^\s]+)/ ? $1 : () } grep { /Acct:/ }
    is a long way to write
    map { /Acct:([^\s]+)/ }
      thank you - using your example, I have the following
      #! / usr/bin/perl -w use strict; use warnings; use POSIX 'strftime'; my $nm = strftime('%Y', localtime).".txt"; my $filename = 'Facs_Data.txt'; open my $fh, '<', $filename or die "Couldn't open '$filename': $!"; my @lines = map { /:([^\s]+)/ ? $1 : () } # take the stuff between th +e : and the first blank grep { /Acct:/ } <$fh>; # Read a file line by line and sel +ect the lines matching Acct: my $outfile = $_."_"."$nm" for @lines ; print $outfile; #open (OUTFILE, ">$outfile"); # do whatever with the values in @lines #print "$_\n" for @lines; close($filename);

      root@localhost:~/GoldenLFiles# perl facs.pl Use of uninitialized value $outfile in print at facs.pl line 17, <$fh> line 168801.

      If I comment the print $outfile to see the output I get the error above. What am I missing here? Thanks in advance
        my $outfile = $_."_"."$nm" for @lines ;

        This line will set/declare $outfile in a loop, which is unlikely to be what you want.

        Did you want a loop over @lines instead? Or did you want to take the first element of @lines?

        print sprintf "Have %d items\n", 0+@lines; my $item = $lines[0]; my $outfile = $item . '_' . $nm; print "$outfile\n";

        I tried the following code with the input data in the __DATA__ section for convenience:

        #! / usr/bin/perl -w use strict; use warnings; use POSIX 'strftime'; my $nm = strftime('%Y', localtime).".txt"; my @lines = map { /:([^\s]+)/ ? $1 : () } # take the stuff between th +e : and the first blank grep { /Acct:/ } <DATA>; # Read a file line by line and select the lines ma +tching Acct: print sprintf "Have %d items\n", 0+@lines; my $item = $lines[0]; my $outfile = $item . '_' . $nm; print "$outfile\n"; print $outfile; #open (OUTFILE, ">$outfile"); # do whatever with the values in @lines #print "$_\n" for @lines; __DATA__ foo Acct:123 Acct:456 bar

        Note that you have a close($filename), which likely should be close($fh) in your code.