CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
Search Posts SEARCH
Who's Online WHO'S
Log in LOG

Home: Perl Programming Help: Beginner:
command line option -n , -p with multiple files...



May 30, 2017, 10:43 AM

Post #1 of 7 (5337 views)
command line option -n , -p with multiple files... Can't Post

 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 the '<>'
- does it already concatenated in shell files, mentioned as arguments?
Or perl do it inside somehow?
Maybe it opening each file as standard-input?!
If so, is it possible to get its name?

Will appreciate help, if you get some idea!
(I understand, I could write everything without the '-n' or '-p', but would like to have that shortage be used,... if possible)


May 30, 2017, 1:59 PM

Post #2 of 7 (5332 views)
Re: [alex5161] command line option -n , -p with multiple files... [In reply to] Can't Post

It can be done, but it is not easy. You have to study the pseudo code for <> in the IO OPERATORS section of perlop to understand what is going on. I devised the following demo. You have to keep track of the current file yourself.

C:\Users\Bill\forums\guru\alex>type a.txt 
I am from file 'a'.

C:\Users\Bill\forums\guru\alex>type b.txt
I am from file 'b'.

C:\Users\Bill\forums\guru\alex>type c.txt
I am from file 'c'.

#! /usr/bin/perl -n
use strict;
use warnings;
print "BEGIN: @ARGV\n";
our $CUR_FILE_NAME = $ARGV[0];

if (!defined $ARGV[0] or $NEXT_FILE_NAME ne $ARGV[0]) {
print $CUR_FILE_NAME, ': ', $_, "\n";

C:\Users\Bill\forums\guru\alex> a.txt b.txt c.txt
BEGIN: a.txt b.txt c.txt
a.txt: I am from file 'a'.

b.txt: I am from file 'b'.

c.txt: I am from file 'c'.

UPDATE: The name of the current input file in available in the special variable $ARGV. This is documented in the section of perlop on the operator <>.
Good Luck,

(This post was edited by BillKSmith on May 30, 2017, 2:48 PM)

Veteran / Moderator

May 30, 2017, 2:14 PM

Post #3 of 7 (5332 views)
Re: [alex5161] command line option -n , -p with multiple files... [In reply to] Can't Post

I have not done any testing, but in order for $. to reset for each file, you'll need to explicitly close the filehandle after testing for eof. The filehandle is ARGV (not sure if it needs to be upper or lowercase).

(This post was edited by FishMonger on May 30, 2017, 2:15 PM)


Jun 1, 2017, 6:05 AM

Post #4 of 7 (5288 views)
Re: [FishMonger] command line option -n , -p with multiple files... [In reply to] Can't Post

 I have reasonable answer on another forum:
Generally, it is about that the '<>' receives the files from the @ARGV one-by-one (probably, by 'shift' command) into the $ARGV and that could be used perfectly.
Here is my example (based on solution from mentioned forum):

/tst > for fl in fl{1..3}; do echo -e " this is $fl file\n Ending $fl file line\n">$fl; done 
/tst > perl -ne 'if ($cr ne $ARGV){$.=1;$cr=$ARGV;} print "$cr(\$ARGV[0]=$ARGV[0]): $. - $_";' fl[0-3]
fl1($ARGV[0]=fl2): 1 - this is fl1 file
fl1($ARGV[0]=fl2): 2 - Ending fl1 file line
fl1($ARGV[0]=fl2): 3 -
fl2($ARGV[0]=fl3): 1 - this is fl2 file
fl2($ARGV[0]=fl3): 2 - Ending fl2 file line
fl2($ARGV[0]=fl3): 3 -
fl3($ARGV[0]=): 1 - this is fl3 file
fl3($ARGV[0]=): 2 - Ending fl3 file line
fl3($ARGV[0]=): 3 -
/tst >


Jun 1, 2017, 8:34 AM

Post #5 of 7 (5283 views)
Re: [alex5161] command line option -n , -p with multiple files... [In reply to] Can't Post

The Explanation for the answers your received has almost nothing to do with -n and everything to do with <>.

All that -n does for you is to create a while loop as we can see in the documentation of -n in perlrun

causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like sed -n or awk:
1. LINE:
2. while (<>) {
3. ... # your program goes here
4. }

The details of <> in a while loop are documented in The IO OPERATOR section of perlop

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
1. while (<>) {
2. ... # code for each line
3. }

is equivalent to the following Perl-like pseudo code:
1. unshift(@ARGV, '-') unless @ARGV;
2. while ($ARGV = shift) {
3. open(ARGV, $ARGV);
4. while (<ARGV>) {
5. ... # code for each line
6. }
7. }

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.)

The variable $ARGV is available to the perl program. Refer to the section of perlvar related to 'Variables related to filehandles'

Contains the name of the current file when reading from <> .

Note: This variable was not available in very old versions of perl. I have not been able to find where it was added. Clearly, I should have read the current documents more carefully before posting my first reply.Blush
Good Luck,


Jun 1, 2017, 9:49 AM

Post #6 of 7 (5280 views)
Re: [BillKSmith] command line option -n , -p with multiple files... [In reply to] Can't Post

 Appreciate your effort writing everything.
(BTW, my question, actualy, asked exactly about the '<>' in '-n'-option processing. Maybe, even without the '-n' it still handling @ARGV in the same way, but I have meat it exactly in the '-n' or '-p'; so, that have asked.)

Veteran / Moderator

Jun 1, 2017, 10:00 AM

Post #7 of 7 (5279 views)
Re: [alex5161] command line option -n , -p with multiple files... [In reply to] Can't Post

perl -ne 'print "$ARGV: $. - $_"; close ARGV if eof ARGV' fl[0-3]

(This post was edited by FishMonger on Jun 1, 2017, 10:02 AM)


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives