Reputation: 89
I want to merge the first column of input1.txt and the third column of input2.txt. How can I do it? My code doesn't do what I want.
Input1:
1 6
2 7
3 8
4 9
Input2:
a 4 8
b 6 7
c 3 4
d 2 6
Requested output:
1 8
2 7
3 4
4 6
My code:
#!/usr/bin/perl
use strict;
use warnings;
open my $input1, '<', "input1.txt" or die qq{Failed to open "input1.txt" for writing: $!};
open my $input2, '<', "input2.txt" or die qq{Failed to open "input2.txt" for writing: $!};
open my $outfile, '>', "outfile.txt" or die qq{Failed to open "outfile.txt" for writing: $!};
while(<$input1>)
{
my @columns1 = split;
print $outfile join("\t", $columns1[0], "\n");
}
while(<$input2>)
{
my @columns2 = split;
print $outfile join("\t", $columns2[2], "\n");
}
close($input1);
close($input2);
close($outfile);
Upvotes: 2
Views: 872
Reputation: 77075
It doesn't have to be this complicated. Read the first file's first column in an array and print it along with the third field of second file. Unless you have files with different number of rows, this should work just fine.
perl -lane'
BEGIN { $x = pop; @col1 = map { (split)[0] } <>; @ARGV = $x }
print join " ", $col1[$.-1], $F[-1]
' input1 input2
1 8
2 7
3 4
4 6
Upvotes: 1
Reputation: 571
Your code print serially, but you need is parallel
#!/usr/bin/perl
use strict;
use warnings;
open my $input1, '<', "input1.txt" or die qq{Failed to open "input1.txt" for writing: $!};
open my $input2, '<', "input2.txt" or die qq{Failed to open "input2.txt" for writing: $!};
open my $outfile, '>', "outfile.txt" or die qq{Failed to open "outfile.txt" for writing: $!};
my ($line1, $line2);
while(1)
{
$line1 = <$input1> || '';
$line2 = <$input2> || '';
my @columns1 = split ' ', $line1;
my @columns2 = split ' ', $line2;
print $outfile join("\t", $columns1[0], $columns2[2]), "\n";
last if !$line1 && !$line2;
}
close($input1);
close($input2);
close($outfile);
Upvotes: 1
Reputation: 2103
Another way to get the requested output is to use one while loop instead of two:
mod.pl
#!/usr/bin/perl
use strict;
use warnings;
open my $input1, '<', "input1.txt" or die qq{Failed to open "input1.txt" for writing: $!};
open my $input2, '<', "input2.txt" or die qq{Failed to open "input2.txt" for writing: $!};
open my $outfile, '>', "outfile.txt" or die qq{Failed to open "outfile.txt" for writing: $!};
while(my $l1 = <$input1>){
my $l2 = <$input2>;
chomp $l1;
chomp $l2;
my @columns1 = split(/ /, $l1);
my @columns2 = split(/ /, $l2);
print $outfile join("\t", $columns1[1-1], $columns2[3-1]),"\n";
}
close($input1);
close($input2);
close($outfile);
#$ perl mod.pl
#$ cat outfile.txt
1 8
2 7
3 4
4 6
Upvotes: 2
Reputation: 1434
Do this:
$filename1 = $ARGV[0]; #for taking input1.txt as the first argument
$filename2 = $ARGV[1]; #for taking input2.txt as the second argument
@data1;
@column1;
open(INPUT_FILE, $filename1)
or die "Couldn't open $filename1!";
while (<INPUT_FILE>) {
my $currentLine = $_; #read the input file one line at a time, storing it to $currentLine
@data1 = split " ", $currentLine; #split your line by space
$firstcolumn = $data1[0]; #store the first column's data
push @column1, $firstcolumn ; #push the first column's data into an array
}
@data2;
@column3;
open(INPUT_FILE, $filename2)
or die "Couldn't open $filename2!";
while (<INPUT_FILE>) {
my $currentLine = $_;
@data2 = split " ", $currentLine;
$thirdcolumn = $data2[2]; #store the third column's data
push @column3, $thirdcolumn ;
}
$size = @column1;
open (OUTPUTFILE, '>>outfile.txt');
for($i = 0; $i < $size; $i++){
print OUTPUTFILE "$column1[$i] $column3[$i]\n"; #writing each entry into the outfile.txt
}
close(INPUT_FILE);
close (OUTPUTFILE);
And when you run your perl program in command line, do:
yourprogram.pl input1.txt input2.txt outfile.txt
And it should work.
I tried the program and opened the outfile.txt and your requested output is in there.
Upvotes: 1