Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
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 avoiding work at the Monastery: (5)
As of 2014-12-27 02:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls