-1

I am trying to run this program that I wrote and I keep getting an error message that states the following

Use of uninitialized value $ARGV[1] in substitution iterator at ./replaceName.pl line 22.

since the value is the name that is passed from the command line and is the second argument I am not sure what is wrong.

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


@FILES = glob("*.txt");

foreach my $file(@FILES){
    if( !defined($ARGV[2]) ){
         $outfile = "$file.modified.txt";
    }
    else {
        $outfile = $ARGV[2];
    }

    open FILE, "< $file" or die("File not found");
    @lines = <FILE>;
    close FILE;

    open OUT, ">", $outfile;
    foreach my $line (@lines) {
        $line =~ s/YourName/$ARGV[1]/gi;
        print OUT $line;
    }
    close OUT;
}
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
jmattioli
  • 11
  • 2
  • 3
    Don't forget that arrays are indexed from 0 in Perl, and the elements of @ARGV do not include the program name. You should probably be using `$ARGV[0]` and `$ARGV[1]`. You can check this by printing out the values of the array — index and value at the index. See [perldoc perlvar](http://perldoc.perl.org/perlvar.html): _The array @ARGV contains the command-line arguments intended for the script. $#ARGV is generally the number of arguments minus one, because $ARGV[0] is the first argument, not the program's command name itself. See $0 for the command name._ – Jonathan Leffler Nov 25 '15 at 20:55
  • thank you I was counting the program as the first argument. changed the 1 to a 0 and works great now – jmattioli Nov 25 '15 at 21:08
  • yes I changed that when I changed the other because i realized that there would never be a 3rd argument – jmattioli Nov 25 '15 at 21:18
  • 1
    I'd recommend using the `strict` pragma, and declare variables with `my`. Also, using bareword filehandles is obsolete. See [Why declare Perl variable with “my” at file scope?](http://stackoverflow.com/questions/24334008/why-declare-perl-variable-with-my-at-file-scope) and [Why does Perl open() documentation use two different FILEHANDLE styles?](http://stackoverflow.com/questions/17376148/why-does-perl-open-documentation-use-two-different-filehandle-styles) for more information.. – Håkon Hægland Nov 25 '15 at 22:37
  • 1
    It looks like you are looking for the `-i` command line switch: `perl -pi.modified -e's/YourName/Foo/gi' file.txt` – TLP Nov 26 '15 at 09:50

1 Answers1

3

Don't forget that arrays are indexed from 0 in Perl, and the elements of @ARGV do not include the program name. You should probably be using $ARGV[0] and $ARGV[1]. You can check this by printing out the values of the array — index and value at the index.

See perldoc perlvar:

The array @ARGV contains the command-line arguments intended for the script. $#ARGV is generally the number of arguments minus one, because $ARGV[0] is the first argument, not the program's command name itself. See $0 for the command name.

Note that this means that if you run:

perl script.pl something or-another

the @ARGV array has two entries: something and or-another in elements 0 and 1 respectively. Similarly if the script is executable:

script.pl something or-another

If you check $ARGV[2], you will be using the default file name with either of the invocations shown — change the 2 to a 1. Also, you should be able to move the test and assignment to $outfile outside the loop, and only open that file just once. At the moment, you zap it for each new file, so effectively you only process the last file.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278