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

Hi Monks!

I've been working through a Perl intro book as I want to understand Perl better and use it at work. I have developed this simple test file below that uses regular expressions and tags to pull info from a file. Right now, I have to hard code the file name in the Perl script. I'd like to be able to type the file path at the command prompt to point this script at various files in different locations. I thought that I could perhaps use @ARGV to help do this, but perhaps not. Here's what I've done so far:
use strict; @ARGV == 1 or die "Specify a file path\n"; open(FILE, $ARGV) or die "Cannot open file: $!\n"; while (<>) { /(\S+)\s+\S+\s+(\S+)\s+(.*)/; #testing regex and tags print "$1, $2, $3\n"; #testing printing } close FILE; print "Done!\n";
My thinking is that I could use @ARGV to do something like this from the command prompt:
myperlscript.pl open, "C:/path/to/file/on_windows_pc/file.txt"

Right now, my program just reaches the @ARGV == 1 line and prints out the die statement. I've tried variatons of @ARGV like @ARGV == 0 and different command line statements too. I must be using @ARGV incorrectly and would appreciate it if anyone could point out the proper way to dynamically point Perl to different files without coding it in. Thank you!!

Replies are listed 'Best First'.
Re: Using @ARGV
by thundergnat (Deacon) on Dec 03, 2005 at 18:12 UTC

    You have several problems. You are supplying two arguments on the command line so the size of @ARGV is going to be 2.

    You would be better off checking to see if @ARGV contains anything and continuing from there.

    You are opening the file handle FILE, then reading from STDIN, so you probably are not getting what you expect.

    You should never use the captured variables from a regex without checking to see if the match succeded.

    use warnings; #<-- also a good idea, especially if you are just starti +ng perl programming use strict; die "Specify a file path\n" unless @ARGV; open my $fh, shift or die "Cannot open file: $!\n"; while (<$fh>) { if (/(\S+)\s+\S+\s+(\S+)\s+(.*)/){ #testing regex and tags print "$1, $2, $3\n"; #testing printing } } close $fh; print "Done!\n";

    Then leave 'open' out of the command line.

    myperlscript.pl "C:/path/to/file/on_windows_pc/file.txt"
Re: Using @ARGV
by davidrw (Prior) on Dec 03, 2005 at 18:41 UTC
    To clarify a little, especially for a novice, i would write thundergnat's line:
    open my $fh, shift or die "Cannot open file: $!\n";
    as:
    # do all the assignments from ARGV here my $filename = shift @ARGV or die "A filename parameter is required"; # explicitly open for read; and make sure filename is in the error mes +sage for reference open FILE, '<', $filename or die "Cannot open file '$filename': $!\n"; while(<FILE>){ ... } close FILE;
    Also worth mentioning here to OP is that using Data::Dumper for debugging can be very useful (sort of trivial here, but a good general technique):
    use Data::Dumper; die Dumper \@ARGV; # see what's really in there ...
    Also note that further down the line you may want to check out any of the GetOpt or other modules that do nice command-line parameter processing for you...
Re: Using @ARGV
by Tech77 (Novice) on Dec 04, 2005 at 23:20 UTC

    Many thanks to everyone who replied.

    I've tested all the variations provided and appreciate the help from thundernat, joost, and merlyn. I'm also going to test out the module mentioned by davidrw. I am also reviewing how shift is used in this context as well.

    I'm just beginning on this and am creating and using very simple Perl programs and the direction and advice I get here really helps me make progress! For example, now I've just learned two different ways to grab files and run them through my regex. I'm going to apply this to some other scripts that I have. Thank you all.