in reply to Re^2: Simple Perl file rename
in thread Simple Perl file rename

@ARGV would be an Array with four entries like this right?
Yes, except for the new lines, \n. Prove this to yourself with a test script:
use strict; use warnings; print "These are the ", scalar @ARGV, " arguments:\n"; my $i = 0; for (@ARGV) { print "ARGV[$i] = $_\n"; $i++; }

prints:

These are the 4 arguments: ARGV[0] = s/foo/bar/ ARGV[1] = file1.txt ARGV[2] = file2.txt ARGV[3] = file3.txt

Alternately, you can use Data::Dumper:

use strict; use warnings; use Data::Dumper; print Dumper(\@ARGV);

prints:

$VAR1 = [ 's/foo/bar/', 'file1.txt', 'file2.txt', 'file3.txt' ];
What I do not understand is how the script determines which files to put into @ARGV. At which point is "*.txt" being evaluated? Or is it the shell that tells the script which files in the directory match the pattern *.txt?
The shift built-in function removes element 0 from the @ARGV array, shifting the remaining elements [1:3] down to new positions [0:2]. Again, here is a simple test script:
use strict; use warnings; my $op = shift; # same as: my $op = shift @ARGV; print "These are the ", scalar @ARGV, " arguments:\n"; my $i = 0; for (@ARGV) { print "ARGV[$i] = $_\n"; $i++; }

prints:

These are the 3 arguments: ARGV[0] = file1.txt ARGV[1] = file2.txt ARGV[2] = file3.txt

Replies are listed 'Best First'.
Re^4: Simple Perl file rename
by Anonymous Monk on Jul 28, 2008 at 21:09 UTC
    Hi toolic,

    thank you for your quick reply. I understand what shift does in this script. What I don't understand is how all txt files in the directory end up in @ARGV.

    When I copy and paste your code, what I get is:

    These are the 2 arguments: ARGV[0] = s/\.txt\.mex// ARGV[1] = *.txt

    And this also makes sense to me, because how would the script be able to know which files in the directory match '*.txt'? Doesn't there have to be another process that matches '*.txt' against all files in the directory first?

    Arian
      When I copy and paste your code
      Since I provided 3 sets of code and output data, I am not sure which one you ran.

      Let's try another approach...

      > ls *.txt file1.txt file2.txt file3.txt > cat test.pl #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; print Dumper(\@ARGV); > ./test.pl 's/foo/bar/' file*.txt $VAR1 = [ 's/foo/bar/', 'file1.txt', 'file2.txt', 'file3.txt' ]; >

      My operating system in Linux. I have 3 *.txt files in my current directory. When I run my test.pl script, it simply prints out the contents of the @ARGV array, which correspond to the things which appear on the test.pl command line. The 1st thing on the command line is the string corresponding to the substitution operator. The 2nd thing on the command line is a file specifier using the standard Unix wildcard character (*), which gets expanded into 3 filenames.

      Are you on a *nix OS, or are you on Windows, or a Mac?

      Are you familiar with the concept of wildcard expansion?

        Thanks a lot toolic,

        "wildcard expansion" gave me the hint I needed. To cite from another thread here Your problem is that Unix expands wildcards before passing them to the program. Windows doesn't do this, prefering to let the program carry out it's own wildcard expansion.

        Hence I just have to glob the files in my Perl script,

        @ARGV= map glob, @ARGV;

        does the trick.

        Thank you very much for your help!

      sorry for the mistake in the 's///' bit, but it doesn't change the result