Komal
Komal

Reputation: 41

Awk not working inside a perl scipt?

I am trying to execute below awk command inside a perl script, but it is failing.

#!/usr/bin/perl

print `awk -F, '{print $NF}' f1.txt > f2.txt`

This is the error:

syntax error at ./MO.pl line 3, near "print"
Execution of ./MO.pl aborted due to compilation errors.

Can anyone please help what I am doing wrong here?

Upvotes: 0

Views: 520

Answers (3)

David W.
David W.

Reputation: 107040

This is a Perl error and has nothing to do with your awk script itself. The error is usually seen when the previous statement doesn't have a semicolon at the end.

Here's a very simple program (which should include use strict; and use warnings;, but I wanted to emulate what you have).

#! /usr/bin/env perl
#

print "Hello, World\n"  # Line 4
print "Hello, Back\n";  # Line 5

And the error message is:

syntax error at test.pl line 5, near "print"
Execution of test.pl aborted due to compilation errors.

Note the error is near the print in Line #5, but the error is actually at the end of Line #4 where I'm missing a semicolon.

Running your exact program works on my system (although doesn't quite produce the results you want). I am assuming this isn't your exact program, but instead a simplification of your program. Is there a statement before that print?

Several other things:

  • You're redirecting your awk output, so there's nothing to print.
  • Use strict and warnings.
  • Better to use qx(....) than backticks (grave accent). It's more readable and allows you to do quoted executable in quoted executable.
  • Watch for Perlisms in your code. The $NF is interpreted by Perl, and without the use strict;, doesn't give you an error. Instead, the print in your Awk statement is a null print which prints the entire line.
  • Why do you use print if nothing is printing out? You're better off in this position to use system which allows you to put single quotes around your entire statement:

    system q(awk -F, '{print $NF}' f1.txt > f2.txt);

    This way, $NF doesn't have to be quoted.

  • Why are you doing Awk in a Perl program? Perl will do anything Awk will do and do it better:

Here's a version of your program using plain ol' Perl:

#! /usr/bin/env perl

use strict;
use warnings;
use autodie;

while ( my $line = <> ) {
    my @array = split /\s*,\s*/, $line;
    print $array[-1];
}

To run this program:

$ test.pl f1.txt > f2.txt

Yes, it's longer, but half of the program is taken up by pragmas that all Perl programs should use.

I'm sure people smarter than me can turn this into a Perl one-liner.

Upvotes: 2

Greg Morris
Greg Morris

Reputation: 189

If there are more lines in the script, you need a semi-colon at the end of the print statement.

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246877

Since you're redirecting the awk output, there's nothing for perl to print. You might as well use system and the quoting operator q():

system q(awk -F, '{print $NF}' f1.txt > f2.txt)

Or, of course, do it in perl, which saves you from having to spawn a shell and then spawn awk:

open my $in, '<', 'f1.txt';
open my $out, '>', 'f1.txt';
while (<$in>) {
    print $out (split " ")[-1], "\n";
}
close $in;
close $out;

Upvotes: 1

Related Questions