selami
selami

Reputation: 89

How can I merge some columns of two files using perl?

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

Answers (4)

jaypal singh
jaypal singh

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

Dim_K
Dim_K

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

David L.
David L.

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

hiew1
hiew1

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

Related Questions