Perl command line option '-n','-p' and multiple files: can it know a file name of a printed line?

I am looking for help in processing of those options: '-n' or '-p'
I understand what they do and how to use them.
But, I would like to use them with more than one file (and without any shell-loop; loading the 'perl' once.)
I did try it and -n works on 2 files.
Question is:

  • is it possible to distinguish from which file is a printed line?

So, I use command like:

perl -ne 'print " $.: $_" if /"\d\d"/' ./fl1 ./fl2

It have correctly selected lines, but I would like anyhow to get a file name where from each line is selected.
Not sure how to get it, if that is possible at all in such usage...

I understand the perl is using the

while (<>) {...}

I am not sure what is going to be read by the '<>'

  • does it already concatenated the input files in shell before starting the Perl?
  • Or Perl do it inside somehow?
    Maybe it opening each file as standard-input, redirecting the stdin to a current file?!
    If so, is it possible to get its name?

Will appreciate help, if you get some idea about how it works with more than one file!
(I understand, I could write everything without the '-n' or '-p', but would like to have that shortage be used,... if possible)
Thanks.

perl -ne '$.=1 if $ARGV ne $previous; print "$. in $ARGV: $_" if /\d\d/; $previous=$ARGV' fl[0-9] fl1{0..9}
while (<>) {...}

Read from file(s) given at the command line or from stdin if no file is given.

2 Likes

Thank you, Aia!

So, the '<>' getting files in 'shift' from @ARGV

Only one think I didn't get (acctualy unrelated to question, but) : what is the fl[0-9]?

Whas it assumed the same as next: fl{0..9} ?
So, it would generate list of files: fl1 fl2 .. fl19

They are a couple examples of ways you could call multiple files (even more than just two) at the command line, courtesy of the shell, without writing one by one.

fl[0-9] would expand to fl0 fl1 fl2 ... fl9 if they exist.
fl1{0..9} would expand to fl10 fl11 fl12 fl13 ... fl19 , and expects them to exist.

1 Like

Yes, but:
fl[0-9] (called "Pathname Expansion / Pattern Matching") expands to EXISTING files that match the pattern, fl{0..9} (called "Brace Expansion") yields all strings unconditionally:

echo file[0-9]
file1 file2 file3 file4
echo file{0..9}
file0 file1 file2 file3 file4 file5 file6 file7 file8 file9

Guess which of those exist in my PWD? Both methods do have their applications.

1 Like

I see, thanks Aia, RudiC!
I know the {, ..}, but not the [....]: so, depends on file's existence!

Thanks! Appreciate your help! (And this forum!!)

Also check the eof and eof() functions in the Perl documentation.
The eof function can be used to reset the line number in case multiple files are fed to the perl interpreter.

 $
$ cat -n file1.dat
     1  Data in line 1 of file file_1.dat
     2  Data in line 2 of file file_1.dat
     3  Data in line 3 of file file_1.dat
     4  Data in line 4 of file file_1.dat
     5  Data in line 5 of file file_1.dat
$
$ cat -n file2.dat
     1  Data in line 1 of file file_2.dat
     2  Data in line 2 of file file_2.dat
     3  Data in line 3 of file file_2.dat
     4  Data in line 4 of file file_2.dat
     5  Data in line 5 of file file_2.dat
$
$ cat -n file3.dat
     1  Data in line 1 of file file_3.dat
     2  Data in line 2 of file file_3.dat
     3  Data in line 3 of file file_3.dat
     4  Data in line 4 of file file_3.dat
     5  Data in line 5 of file file_3.dat
$
$ # $. is not reset by itself. Perl numbers the pseudo-file formed from the files listed on the command line
$ perl -lne 'printf("File = %s, Line = %2d : [%s]\n", $ARGV, $., $_)' file1.dat file2.dat file3.dat
File = file1.dat, Line =  1 : [Data in line 1 of file file_1.dat]
File = file1.dat, Line =  2 : [Data in line 2 of file file_1.dat]
File = file1.dat, Line =  3 : [Data in line 3 of file file_1.dat]
File = file1.dat, Line =  4 : [Data in line 4 of file file_1.dat]
File = file1.dat, Line =  5 : [Data in line 5 of file file_1.dat]
File = file2.dat, Line =  6 : [Data in line 1 of file file_2.dat]
File = file2.dat, Line =  7 : [Data in line 2 of file file_2.dat]
File = file2.dat, Line =  8 : [Data in line 3 of file file_2.dat]
File = file2.dat, Line =  9 : [Data in line 4 of file file_2.dat]
File = file2.dat, Line = 10 : [Data in line 5 of file file_2.dat]
File = file3.dat, Line = 11 : [Data in line 1 of file file_3.dat]
File = file3.dat, Line = 12 : [Data in line 2 of file file_3.dat]
File = file3.dat, Line = 13 : [Data in line 3 of file file_3.dat]
File = file3.dat, Line = 14 : [Data in line 4 of file file_3.dat]
File = file3.dat, Line = 15 : [Data in line 5 of file file_3.dat]
$
$ # $. is reset for each file; similar to awk's FNR == NR idiom
$ perl -lne 'printf("File = %s, Line = %2d : [%s]\n", $ARGV, $., $_); close(ARGV) if eof' file1.dat file2.dat file3.dat
File = file1.dat, Line =  1 : [Data in line 1 of file file_1.dat]
File = file1.dat, Line =  2 : [Data in line 2 of file file_1.dat]
File = file1.dat, Line =  3 : [Data in line 3 of file file_1.dat]
File = file1.dat, Line =  4 : [Data in line 4 of file file_1.dat]
File = file1.dat, Line =  5 : [Data in line 5 of file file_1.dat]
File = file2.dat, Line =  1 : [Data in line 1 of file file_2.dat]
File = file2.dat, Line =  2 : [Data in line 2 of file file_2.dat]
File = file2.dat, Line =  3 : [Data in line 3 of file file_2.dat]
File = file2.dat, Line =  4 : [Data in line 4 of file file_2.dat]
File = file2.dat, Line =  5 : [Data in line 5 of file file_2.dat]
File = file3.dat, Line =  1 : [Data in line 1 of file file_3.dat]
File = file3.dat, Line =  2 : [Data in line 2 of file file_3.dat]
File = file3.dat, Line =  3 : [Data in line 3 of file file_3.dat]
File = file3.dat, Line =  4 : [Data in line 4 of file file_3.dat]
File = file3.dat, Line =  5 : [Data in line 5 of file file_3.dat]
$
$