user3654707
user3654707

Reputation: 1

Executing shell command with pipe in perl

I want the output of the shell command captured in variable of a perl script, only the first section of the command before the pipe "|" is getting executed, and there is no error while executing the script

File.txt 
Error input.txt got an error while parsing 
Info  output.txt has no error while parsing 

my $var = `grep Error ./File.txt | awk '{print $2}'`;
print "Errored file $var";

Errored file Error input.txt got an error while parsing

I want just the input.txt which gets filtered by awk command but not happening. Please help

Upvotes: 0

Views: 6450

Answers (2)

Miller
Miller

Reputation: 35198

Always include use strict; and use warnings; in EVERY perl script.

If you had, you'd have gotten the following warning:

Use of uninitialized value $2 in concatenation (.) or string at scratch.pl line 4.

This would've alerted you to the problem in your command, namely that the $2 variable is being interpolated instead of being treated like a literal.

There are three ways to avoid this.

1) You can do what mob suggested and just escape the $2

my $var = `grep Error ./File.txt | awk '{print \$2}'`

2) You can use the qx form of backticks with single quotes so that it doesn't interpolate, although that is less ideal because you are using single quotes inside your command:

my $var = qx'grep Error ./File.txt | awk \'{print $2}\''

3) You can just use a pure perl solution.

use strict;
use warnings;

my ($var) = do {
    local @ARGV = 'File.txt';
    map {(split ' ')[1]} grep /Error/, <>;
};

Upvotes: 2

mob
mob

Reputation: 118605

The $ in $2 is interpolated by Perl, so the command that the shell receives looks like:

grep Error ./File.txt | awk '{print }'

(or something else if you have recently matched a regular expression with capture groups). The workaround is to escape the dollar sign:

my $var = `grep Error ./File.txt | awk '{print \$2}'`

Upvotes: 2

Related Questions