Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Join files using perl

by blue_cowdawg (Monsignor)
on Jan 11, 2013 at 19:23 UTC ( #1012961=note: print w/ replies, xml ) Need Help??


in reply to Join files using perl

      Could somebody help me do this on a faster way? Thanks!

Faster? <shrug!> dunno, but pull up a chair. Here are the two input files..

$ cat file1.txt 1 2 3 4 5 $ cat file2.txt 5 4 3 2 1
and here's some code:
#!/usr/bin/perl -w use strict; use Tie::File; my ($file1,$file2,$fileout) = @ARGV; tie my @ry1,"Tie::File",$file1 or die "$file1:$!"; tie my @ry2,"Tie::File",$file2 or die "$file2:$!"; tie my @out,"Tie::File",$fileout or die "$fileout:$!"; @out=(@ry1,@ry2); untie @out; untie @ry2; untie @ry1;
which gives you this as an output:
$ cat out.txt 1 2 3 4 5 5 4 3 2 1


Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg


Comment on Re: Join files using perl
Select or Download Code
Re^2: Join files using perl
by linseyr (Acolyte) on Jan 11, 2013 at 19:42 UTC
    Thanks, but this wasn't what I wanted. My files looks like:
    ID1 50 ID2 60 ID3 100 FILE2: ID1 20 ID2 100 ID3 10 OUTPUT: ID1 50 20 ID2 60 100 ID3 100 10
      Oh and both files contain more columns, that was my main problem. How do I assign an array as values in an hash?
        I tried this:
        foreach $line (@FILE1){ chomp($line); my($ID, @values) = split("\t", $line); $aref = \@values; $common1{$ID} = $aref; } print $common1{"B01_05_121214_LAP_G1_87_20593"};
        But the output is: ARRAY(0x7f8f4b82d310)

      my mistake. try this:

      #!/usr/bin/perl -w use strict; use Tie::File; my ($file1,$file2,$fileout) = @ARGV; tie my @ry1,"Tie::File",$file1 or die "$file1:$!"; tie my @ry2,"Tie::File",$file2 or die "$file2:$!"; tie my @out,"Tie::File",$fileout or die "$fileout:$!"; my %een=(); my %dat=(); map{ $dat{$_}=[]} grep !$een{$_}++,map { (split(/[\s\t\n]+/,$_))[0] } +(@ry1,@ry2); foreach my $line((@ry1,@ry2)){ my ($key,@vals)=split(/[\s\t\n]+/,$line); push @{$dat{$key}},@vals; } @out=map { join("\t",($_,@{$dat{$_}})) } keys %dat; untie @out; untie @ry2; untie @ry1;
      Using your input files this was tested and gave output that you are looking for...


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      Consider this:
      #!/usr/bin/perl -w use strict; my $FILE1 = <<END; ID1 50 ID2 60 ID3 100 END my $FILE2 = <<END; ID1 20 ID2 100 ID3 10 END my %ids; foreach my $file (\$FILE1, \$FILE2) #just put path name of #FILE1 and FILE2 here. #This ref is special because of #putting the file contents within #the code. #FILE1 and 2 are "hereis" docs. { open (FILE, "<", $file) or die "unable to open $file for read $!"; while (<FILE>) { chomp; # delete trailing \n # here I split on one or more space characters, # A tab char doesn't show up well on this forum's text my ($id, $value) = split (/\s+/, $_); push @{$ids{$id}}, $value; } } #Each key of the hash of %ids contains a reference to #an array of id's. This is called a HoA - Hash of Array foreach my $id (sort keys %ids) { print "$id @{$ids{$id}}\n"; } #This code will run very fast because each line is #only read one time - Input/Output (I/O) is very #"expensive" __END__ OUTPUT: ID1 50 20 ID2 60 100 ID3 100 10

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1012961]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2015-07-04 05:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (57 votes), past polls