Perl - Extract first column from file

Hi,

I want to extract first column from a file and redirect the output to another file in perl.

I am able to do this from command line by executing below commands.

perl -anle 'print $F[0]' Input.dat > Output.dat
perl -ne '@F = split("\t", $_); print "$F[0]\n";' Input.dat > Output.dat
perl -anE 'say "@F[0,1]"' Input.dat > Output.dat

But when I add this in perl script it is not working.

	$cmd = "perl -anle 'print $F[0]' ".$inFile." > ".$outFile;
	system($cmd);
	if ($? != 0)
	{
		errorLog("Could not create file ".$inFile);
	}

Regards
Neethu

You are already inside Perl. There is no point running system() -- which runs a Bourne shell -- to run Perl in commandline again inside a Bourne shell.

It won't quite be a "one-liner" anymore, but it will still be short, and it will also be better-checked for errors.

open(OUTFILE, ">Output.dat") || die("Couldn't open Iutput.dat");
open(INFILE, "<Input.dat") || die("Couldn't open Input.dat");
        while(@F = split("\t", <INFILE>)) { print OUTFILE "$F[0]\n" }
close(OUTFILE); close(INFILE);

try

#!/usr/bin/perl

use strict;
use warnings;

open(IN, "in.txt") or die $!;
open(OUT, ">out.txt") or die $!;

while( <IN>)
{
	my @C =split( /\s+/, $_ );
	print OUT "$C[0]\n";
}

close (IN);
close (OUT);

Using the system() function to execute Perl code inside a Perl script is like using a wheelchair on someone that does not have problems running. Don't let a few more lines of code fool you.

open(IN, "in.txt") or die $!;
open(OUT, ">out.txt") or die $!;
open(OUTFILE, ">Output.dat") || die("Couldn't open Iutput.dat");
open(INFILE, "<Input.dat") || die("Couldn't open Input.dat");

Long time ago, creating files handles in that way was OK in Perl, until other problems appeared with not so good consequences.

Today, it is considered good practice to use lexical variables for filehandles and separate the read or write operator from the filename or filename variable, establishing the rule of thumb of always using a three-arguments to open. And I would like to promote that.

e.i.

#!/usr/bin/perl

use strict;
use warnings;

my $inFile  = "Input.dat";
my $outFile = "Output.dat";

open my $fh_in,  "<", "$inFile"  or die "Could not open $inFile: $!\n";
open my $fh_out, ">", "$outFile" or die "Could not create $outFile: $!\n";

while ( my $line = <$fh_in> ) {
    my $first_column = (split /\s+/, $line)[0];
    print $fh_out "$first_column\n";
}
close $fh_in;
close $fh_out;
1 Like

Thank you all for the reply.
I tried the below code. The file is a tab delimited file. If there is a null value in first column in the third row then it is pulling the second column from that row and saving it in the output file.

#!/usr/bin/perl

use strict;
use warnings;

my $inFile  = "Input.dat";
my $outFile = "Output.dat";

open my $fh_in,  "<", "$inFile"  or die "Could not open $inFile: $!\n";
open my $fh_out, ">", "$outFile" or die "Could not create $outFile: $!\n";

while ( my $line = <$fh_in> ) {
    my $first_column = (split /\t+/, $line)[0];
    print $fh_out "$first_column\n";
}
close $fh_in;
close $fh_out;

Input File:
111 123 456
222 234 567
null 345 678

Output file from above code:
111
222
345

Expected Output:
111
222

In that case it is not tab delimited, use the split/\s+/ as outlined in Aia's post aboce

This is a bit more terse:

open(OUTFILE, ">Output.dat") || die("Couldn't open Iutput.dat");
open(INFILE, "<Input.dat") || die("Couldn't open Input.dat");
        while(@F = split(/\s+/, <INFILE>)) { print OUTFILE "$F[0]\n" }
close(OUTFILE); close(INFILE);

Thank you all... It worked as expected..