vervenumen
vervenumen

Reputation: 667

Perl inside Bash: How to read from pipe and pass arguments to perl at the same time?

Following is the code I am trying out:

echo "a b c" | perl -e 'print $ARGV[0]; print $ARGV[1]; print $_;' "abc" "def"

Output of this code is:

abcdef

I am not able to figure out why "print $_;" is not printing "a b c" as usual. Any ideas?

Upvotes: 4

Views: 5177

Answers (1)

TLP
TLP

Reputation: 67900

You are not using -n or -p, so you are not using <> for standard input. Which you would not do anyway if you have arguments.

Explanation:

When you use -n or -p, it puts a while(<>) loop around your code, like so:

perl -ne ' print ' 

is equal to

perl -e ' while (<>) { print }'

And if you use -p it is:

perl -e ' while (<>) { print } continue { print $_ }'

At this stage, Perl will decide how <> will work by checking @ARGV, where the arguments to the script are stored. If there is anything in there, it will treat the arguments as file names, and try to open and read these files. The file handle will then be called ARGV. At this point, <> cannot be used to read from standard input.

Solution

In other words, using arguments will override the reading from STDIN. So if you want to read from standard input, you use that file handle instead:

echo "a b c" | perl -e ' print @ARGV[0,1]; while (<STDIN>) { print } ' foo bar

Another option would be to clear the @ARGV array beforehand, like so:

echo "a b c"|perl -ne'BEGIN { @x = @ARGV; @ARGV = () }; print @x; print;' foo bar

But that would also print @x one time per line of input you have, which may not be desirable.

Upvotes: 11

Related Questions