RookieOfTheYear
RookieOfTheYear

Reputation: 31

Perl split file into columns with unix command

I have a file with various columns separated by tabs. I' trying to invoke an unix command in perl but it gives me an error ever time

use strict;
use warnings;


system ("awk -F '\t' '{print $1}' file.txt > first_field.tmp");

Upvotes: 0

Views: 470

Answers (3)

Tom Fenech
Tom Fenech

Reputation: 74695

Because you are using double quotes " " around your command, Perl is trying to interpolate the value of $1. You need to escape it:

system ("awk -F '\t' '{print \$1}' file.txt > first_field.tmp");

Or you could use ' quotes, which don't interpolate:

system ('awk -F "\t" "{print $1}" file.txt > first_field.tmp');

...or qx:

qx/awk -F '\t' '{print \$1}' file.txt > first_field.tmp/;

Seeing as you're such a big fan of Perl, I would recommend checking out the documentation regarding the various types of quotes and quote-like operators.

Obviously this is the kind of thing that Perl eats for breakfast, so if you're looking for a native solution I would recommend using what @Miller has posted, or one of the million other ways you could do the same thing in Perl.

An alternative version using the Text::CSV package as suggested by @LeoNerd:

use strict;
use warnings;

{
    use Text::CSV;

    my $csv = Text::CSV->new ( { sep_char => "\t" } )
                    or die "Cannot use CSV: ".Text::CSV->error_diag ();

    open my $fh, "<", "file.txt" or die "file.txt: $!";
    open my $out, ">", "first_field.tmp" or die "first_field.tmp: $!";
    while ( my $row = $csv->getline( $fh ) ) {
        $out->print("$row->[0]\n");
    }
    $csv->eof or $csv->error_diag();
}

Upvotes: 1

LeoNerd
LeoNerd

Reputation: 8542

You have a tab-separated value file. What's wrong with Text::CSV in tab-separated mode then? No need to invoke awk for something like this.

Upvotes: 2

Miller
Miller

Reputation: 35208

Single quote your system command:

system(q{awk -F '\t' '{print $1}' file.txt > first_field.tmp});

Or without the need for an external resource:

use strict;
use warnings;
use autodie;

{
    local @ARGV = 'file.txt';
    open my $fh, '>', 'first_field.tmp';
    while (<>) {
        chomp;
        my @F = split "\t";
        $fh->print("$F[0]\n");
    }
}

Upvotes: 3

Related Questions