0

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.

1
  • Welcome to Stack Overflow. I recommend using lexical file handles consistently, not a mix of lexical and non-lexical file handles. You've got a reference to 'open' in the error message for a close. There seems to be an inordinate amount of file opening and closing. You open the file, read it, close it, open it, write, close it, open it, open an output file, read and write, and then close one but not both of the open files. I'm deeply suspicious of the @row{@fields} = split /\t/;. You don't use List::MoreUtils AFAICS. Commented May 8, 2014 at 2:24

2 Answers 2

1

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;
Sign up to request clarification or add additional context in comments.

Comments

1

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

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.