Andrej Kastrin am Montag, 30. Januar 2006 16.50: > John Doe wrote: > >Andrej Kastrin am Montag, 30. Januar 2006 10.14: > >>Dear all, > >> > >>I have bar separated file: > >>name1|345 > >>name2|201 > >>... > >> > >>I store it into a hash; > >>while (<FILE_A>) { > >> chomp; > >> ($name,$score) = split (/\|/,$_); > >> $hash{$name} = $score; > >>} > > > >Let's assume the resulting hash is %scores. > > > >>Then I have second file: > >>ID - 001 > >>NA - name1 > >>NA - name2 > >> > >>ID - 002 > >>NA - name2 > >>NA - name4 > >>... > >> > >>I match all ID's and NA's: > >> > >>while (<FILE_B>) { > >> chomp; > >> if (/^ID/ { > >> $ID = substr($_,5); > >> } > >> elseif (/^NA/) { > >> $NA = substr($_,5) > >>} > >> > >>Now I have to do somethig like; > >>001 | 345+201 > >>So, I want to read ID and NA fields from second file and then with each > >>ID print the sum of scores from first file. > >>Any suggestion. Which structure should I use to do that. Thank's in > >>advance. > > > >Now you could parse FILE_B and use another twodimensional hash to > > accumulate the scores by ID for each name. The loop could look like > > (untested): > > > >my %sums; > >my $id; > >while (<FILE_B>) { > > chomp; > > next if (($id)=$_=~/^ID - (\d+)/); > > next unless my ($na)=$_=~/^ID - (\w+)/; > > $sums{$id}->{$na}+=$scores{$na}; > >} > > > >foreach my $id (sort keys %sums) { > > print "ID $id\n"; > > foreach my $name (sort keys %{$sums{$id}}) { > > print "name: $name - scores: ", > > $sums{$id}->{$name}, "\n"; > > } > >} > > > >(All handling of possible errors is missing here) > > > > > >hth, > >joe > > I'm totally confused now and I have no more ideas... Thank's for your > reply Joe, but I didn't manage. Here is the more real example:
My answer above is obviously not appropriate to the following quite different example... [1] > First file: (I modify it) > 270|Germany|Hospitals|Poland > 272|Germany|History > 273|Physiology|Poland|Portraits Quite different from: name1|345 [2] > Second file: > Germany|100 > History|200 > Hospitals|50 > Poland|50 > Physiology|10 > Portrait|10 (I assume you mean 'portraits' here) Quite different from: ID - 001 NA - name1 NA - name2 ID - 002 [3] > Output file: > 270|100|50|50|200 #270 is the key in table 1; > 100, 50, 50 are values for > nouns from second file, 200 is the sum of them > 272|100|200|300 > 273|10|50|10|70 Ok, you want [3] from [1] and [2]? If yes, here is the script, I tested it, and it produces the output you like: #!/usr/bin/perl use strict; use warnings; # Make a lookup hash of file 2. # haskeys are keys, hashvalues names of the file. # It is assumed that a name only occurs once in the file. # my %lookup; open (my $fh2, '<', 'file2') or die; while (<$fh2>) { chomp; my ($name, $score)=split /\|/; $lookup{$name}=$score; } close $fh2 or die; # Now in every line of file1 all names are replaced # by their score (?) value found in the lookup hash # and a sum is added at the end. The line is # directly printed out. # open (my $fh1, '<', 'file1') or die; open (my $fh3, '>', 'file3') or die; while (<$fh1>) { chomp; my ($num, @entries)=split /\|/; # replace names by scores. If no score found, # take score=0 # @entries=map {$lookup{$_}||0} @entries; my $sum=0; $sum+=$_ for @entries; print $fh3 join '|', $num, @entries, $sum; print $fh3 "\n"; } close $fh1 or die; close $fh3 or die; -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>