Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't $ARGV[0] initialized by the file name I pass this perl one liner?

Tags:

perl

I have a perl one liner that supposed to export each individual line in an xml file to it's own separate file with the name of the original file and then the line number within that file that it came from.

For instance, if the xml file is called "foo.xml" and it has 100 lines in it then I want to have a hundred files called, "foo_1.xml", "foo_2.xml", "foo_3.xml", etc.

I thought that the name of the file that I pass to the one liner would be available via ARGV, but it's not. I'm getting a "uninitialized value in $ARGV[0]" error when I run this:

perl -nwe 'open (my $FH, ">", "$ARGV[0]_$.\.xml"); print $FH $_;close $FH;' foo.xml

What am I overlooking?

like image 325
phileas fogg Avatar asked Oct 03 '11 22:10

phileas fogg


2 Answers

When using the magic <> filehandle (which you're doing implicitly with the -n option), Perl shifts the filenames out of @ARGV as it opens them. (This is mentioned in perlop.) You need to use the plain scalar $ARGV, which contains the filename currently being read from:

perl -nwe 'open (my $FH, ">", "${ARGV}_$.\.xml"); print $FH $_;close $FH;' foo.xml

(The braces are necessary because $ARGV_ is a legal name for a variable.)

like image 60
cjm Avatar answered Nov 03 '22 02:11

cjm


cjm has the correct answer. However, it will create files such as foo.xml_1.xml. You asked for foo_1.xml, etc.

perl -nwe '
my ($file) = $ARGV =~ /(\w+)/;
open my $fh, ">", $file . "_$..xml" or die $!;
print $fh $_;
' foo.xml
like image 36
TLP Avatar answered Nov 03 '22 00:11

TLP