Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl - passing an array to subroutine

I'm in the process of learning Perl and am trying to write a script that takes a pattern and list of files as command line arguments and passes them to a subroutine, the subroutine then opens each file and prints the lines that match the pattern. The code below works; however, it stops after printing the lines from the first file and doesn't even touch the second file. What am I missing here?

#!/usr/bin/perl
use strict;
use warnings;

 sub grep_file 
 {
  my $pattern = shift;
  my @files = shift;

  foreach my $doc (@files) 
  {
    open FILE, $doc;
    while (my $line = <FILE>) 
    {
      if ($line =~ m/$pattern/) 
      {
        print $line;
      }
    }
  }

grep_file @ARGV;
like image 717
Jukodan Avatar asked Jan 31 '26 08:01

Jukodan


2 Answers

Shift pops an element from your parameter (see: http://perldoc.perl.org/functions/shift.html).

So @files can only contain one value.

Try

sub foo
{
 my $one = shift @_;
 my @files = @_;
 print $one."\n";
 print @files;
}

foo(@ARGV);
like image 157
Stefan Avatar answered Feb 02 '26 00:02

Stefan


There is little reason to use a subroutine here. You are just putting the whole program inside a function and then calling it.

The empty <> operator will read from all the files in @ARGV in sequence, without you having to open them explicitly.

I would code your program like this

use strict;
use warnings;

my $pattern = shift;
$pattern = qr/$pattern/; # Compile the regex

while (<>) {
  print if $_ =~ $pattern;
}
like image 45
Borodin Avatar answered Feb 01 '26 23:02

Borodin