Maybe I'm not quite understanding, it seems to me that the procedure should be either
- Read file 2 (not 1) into a hash
- For each line of file 1
- Compare; if match add info to hash
- Print hash to file
or, e.g. if file 2 is too large:
- Read file 1 into a hash
- For each line of file 2
- Compare; if match add info to line
- Print line to file (regardless of match)
| [reply] |
Summarizing
File 1 contains
Field1 Field2 Field3 Field4 Field5
File 2 contains
Field1..Field15
I need to compare Field11 from file 2 with field1 from file 1 and if match add Field5 from file1. If it doesn't match I need to print the line in any case. The problem is to print the line to file regardless of the match, since the code I posted above.....it will write the line as many times as they key I have in the hash obtained from file 1
I hope to have been clearer. Thanks for your idea!
| [reply] |
I have a tab delimited text file 1 with 5 different fields. From this file I need the field five associated to the field 1
open my $file, '<', "file1";
while ($file){
chomp;
my ($one,$too,$tree,$fool,$flin) = split /\t+/, $_, 5;
print $one, " ", $flin;
}
From this file I need the field five associated to the field 1
ok, after read again I see that you want a hash... then define a hash first and change the print line for this line
$hash{$one} = $flin; | [reply] [d/l] [select] |
I don't think you need to test the keys, just print what you have
} elsif ( $rsfound =~ m/^rs[0-9]/i ){
print OUTFILE "$_\t $out{$rsfound}\n";
}
poj | [reply] [d/l] |
Now I have a tab delimited text file2 with 15 fields and I want to add the info of field 5 from file1, if the field 11 (of file 2) is equal to the field 1 of file 1.
this is more tricky, temptatively and untested, open file 2 first as usual...
for my $key ( keys %hash ) {
while ($file2){
if (
/ \a
.*?\t # field 1 of file 2
.*?\t # field 2 of file 2
.*?\t # field 3 of file 2
.*?\t # field 4 of file 2
.*?\t # field 5 of file 2
.*?\t # field 6 of file 2
.*?\t # field 7 of file 2
.*?\t # field 8 of file 2
.*?\t # field 9 of file 2
.*?\t # field 10 of file 2
$key \t
.*?\t # field 12 of file 2
.*?\t # field 13 of file 2
.*?\t # field 14 of file 2
.*\z # field 15 of file 2
/x)
{ do something...}
else {next}
}
| [reply] [d/l] [select] |
I did not understand your solution
Actually the code till here is
while (<MYINFILE>) {
chomp ($_);
@line = split (/\t/, $_);
$rsfound = $line[11] ;
my$loc = $line[0] ;
if ($loc =~ m/location/i)
{print OUTFILE "$_\t YRI_iHs\n" ; }
elsif ($rsfound =~ m/^rs[0-9]/i)
{foreach my$key (keys(%out)) {
if ( $rsfound eq $key )
{print OUTFILE "$_\t $out{$key}\n";}
}
This script show me only the line of file 2 where i find the match with the key of the hash %out. I actually need to print all the lines, even the ones without the match.
Sorry from file 1 I go the hash %out with field1 as keys and field5 as values | [reply] [d/l] |
If I understand your stated goal, I think you just need to move the print statement for the lines from file2 so that it's outside the conditional -- that is, you are going to print every line from file2, but you will only be altering the contents of some of the lines.
Also, since you have a hash for the relevant values from file1, you don't need to loop over all the hash keys when reading each line from file2. You just need to test of the field-11 value from file2 exists as a hash key from file1.
Putting those two things together:
use strict;
use warnings;
my ( $file1, $file2 ) = ( 'file1_name_here', 'file2_name_here' );
# read hash keys and values from file1:
open( F, '<', $file1 ) or die "$file1: $!\n";
my %mods;
while (<F>) {
chomp;
my ( $key, $val ) = ( split /\t/ )[0,4];
$mods{$key} = $val;
}
close F;
# read and rewrite file2, altering certain lines as needed
open( IN, '<', $file2 ) or die "$file2: $!\n";
open( OUT, '>', "$file2.new" ) or die "$file2.new: $!\n";
while (<IN>) {
chomp;
my ( $loc, $chk ) = ( split /\t/ )[0,11]; # or should it be [0,10
+]?
if ( $loc =~ /location/ ) { # modify some input lines as needed
$_ .= "\t YRI_iHs\n";
}
elsif ( exists( $mods{$chk} )) {
$_ .= "\t$mods{$chk}\n";
}
print OUT; # print every input line to output file
}
close IN;
close OUT;
# you could rename the output to replace the original...
# rename "$file2.new", $file2;
# (but you might want to check the output first)
If that's not what you meant, then you'll need to explain your goal more clearly, possibly with some sample data.
(updated to fix typo in last comment line) | [reply] [d/l] |