user2767090
user2767090

Reputation: 19

extracting data from tab delimited file to new text file using perl script

Input:

NAME Age Occupation Place
X1   43   Artist     Italy
X2   42   Artist     Germany
Y1   56   Artist     France

I need to extract the NAME and age column.

My code:

#!/usr/bin/perl
use strict;
use warnings;
use List::MoreUtils;
my $file = @ARGV[0];
open(FH, "< $file") or die "Cannot open $file for reading: $!";
my @array = <FH>;
close FH or die "Could not open file: $!";
open(OUT, ">$file") or die "Cannot open $file for write access: $!";
print OUT splice(@array,4);
close OUT or die "Could not close file: $!";
open(MYFILE,"< $file") or die "Cannot open $file for read access: $!";
open(my $OFILE, '>Output.txt') or die "Cannot create file for output: $!";
my @wanted = ("NAME","AGE");
my @output = qw/NAME AGE/;
my @fields = split /\t/, <MYFILE>;
chomp @fields;
print $OFILE join("\t",@output), "\n";
while(<MYFILE>)
{
    chomp;
    my %row;
    @row{@fields} = split /\t/;
    my @wanted_data = map{$row{$_}} @wanted;
    print $OFILE join("\t", @wanted_data), "\n";
}
close $OFILE or die "Error closing $OFILE: $!";

i am getting error like Use of uninitialized value in join or string at print $OFILE join("\t", @wanted_data), "\n";
So the header alone got print in my output.txt

Thanks, N.

Upvotes: 0

Views: 1050

Answers (2)

Shmuel Fomberg
Shmuel Fomberg

Reputation: 546

You are doing so much unnecessary work here..

Assuming that you know that name and age are the first two columns:

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new;
my $file = $ARGV[0];

open my $fh, "<", $file or die "Cannot open $file for reading: $!";
open my $OFILE, '>', 'Output.txt' or die "Cannot create file for output: $!";

while ( my $row = $csv->getline( $fh ) ) {
   print $OFILE $row->[0], "\t", $row[1], "\n";
}

close $fh;
close $OFILE;

Upvotes: 1

Lee Duhem
Lee Duhem

Reputation: 15121

If you just want the first two columns, you could simply split those lines and ouput the first two fields:

#!/usr/bin/perl

use strict;
use warnings;

use feature qw(say);

use Data::Dumper;

while (<DATA>) {
    chomp;
    my ($name, $age) = split /\s+/;
    say "$name $age";
}

__DATA__
X1   43   Artist     Italy
X2   42   Artist     Germany
Y1   56   Artist     France

Here is a one-liner version:

perl -anE 'say "@F[0,1]"' input.txt

Upvotes: 1

Related Questions