Perl offers this very nice feature:
while ( <> )
{
# do something
}
...which allows the script to be used as script.pl <filename>
as well as cat <filename> | script.pl
.
Now, is there a way to determine if the script has been called in the former way, and if yes, what the filename was?
I know I knew this once, and I know I even used the construct, but I cannot remember where / how. And it proved very hard to search the 'net for this ("perl stdin filename"? No...).
Help, please?
use File::Basename; ... $file = basename($path); Why did $file=$path=~s/.
There are many programs designed for programmers available for download on the web. As a Perl convention, a Perl file must be saved with a . pl or.PL file extension in order to be recognized as a functioning Perl script.
The variable $ARGV
holds the current file being processed.
$ echo hello1 > file1
$ echo hello2 > file2
$ echo hello3 > file3
$ perl -e 'while(<>){s/^/$ARGV:/; print;}' file*
file1:hello1
file2:hello2
file3:hello3
The I/O Operators section of perlop
is very informative about this.
Essentially, the first time <>
is executed, -
is added to @ARGV
if it started out empty. Opening -
has the effect of cloning the STDIN
file handle, and the variable $ARGV
is set to the current element of @ARGV
as it is processed.
Here's the full clip.
The null filehandle "<>" is special: it can be used to emulate the behavior of sed and awk, and any other Unix filter program that takes a list of filenames, doing the same to each line of input from all of them. Input from "<>" comes either from standard input, or from each file listed on the command line. Here's how it works: the first time "<>" is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames. The loop
while (<>) { ... # code for each line }
is equivalent to the following Perl-like pseudo code:
unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }
except that it isn't so cumbersome to say, and will actually work. It really does shift the @ARGV array and put the current filename into the $ARGV variable. It also uses filehandle ARGV internally. "<>" is just a synonym for "<ARGV>", which is magical. (The pseudo code above doesn't work because it treats "<ARGV>" as non-magical.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With