dibonao
dibonao

Reputation: 85

perl does not evaluate bash script correctly

This is my code

my $shell_line_diff=`echo $(($(diff -U 0 ftest1.txt ftest2.txt|grep ^\+|wc -l)-$(diff -U 0 ftest1.txt ftest2.txt|grep ^\-|wc -l)))`;
print "difference in the number of lines is $shell_line_diff\n";

and the evaluated script works fine on Linux bash.

But in perl it gives me the following results:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `echo 1010 1010 10000000 10000003 10000004 10000010(1010 1010 10000000 10000003 10000004 10000010diff -U 0 ftest1.txt ftest2.txt|grep ^+|wc -l)-1010 1010 10000000 10000003 10000004 10000010diff -U 0 ftest1.txt ftest2.txt|grep ^-|wc -l)))'
difference in the number of lines is

What did I do wrong?

Upvotes: 0

Views: 69

Answers (2)

chepner
chepner

Reputation: 531205

Ignoring the actual problem with the code, I would simplify this to

my @lines = qx/diff -U 0 ftest1.txt ftest2.txt/
my $shell_line_diff = grep(/^\+/, @lines) - grep(/^-/, @lines)

This should be much faster, as you are

  1. Only running diff once, not twice
  2. Eliminating several unnecessary processes by not running grep, wc, or the command substitutions that pass the results of the pipelines to the shell's arithmetic expression.

If you really want to keep the shell, you can drop the wc -l command in favor of the -c option to grep, which produces a line count instead of the actual set of lines.

Upvotes: 1

tivn
tivn

Reputation: 1923

This is because your shell command is not quoted. Use temporary variable like this:

my $cmd = 'echo $(($(diff -U 0 ftest1.txt ftest2.txt|grep ^\+|wc -l)-$(diff -U 0 ftest1.txt ftest2.txt|grep ^\-|wc -l)))';
my $shell_line_diff=`$cmd`;
print "difference in the number of lines is $shell_line_diff\n"; 

If you do not quote it properly, $( is interpreted by perl before execute your backtick command (see man perlvar).

Upvotes: 4

Related Questions