0

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?

2
  • 2
    Are you supposed to have two opening brackets (? Commented Apr 12, 2015 at 5:46
  • You're pushing an awful lot of work that you can do directly in Perl out to the shell. Commented Apr 12, 2015 at 14:30

2 Answers 2

4

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

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.