in reply to Get data from a file to search and replace within a second file

One approach is to read the 3rd and 4th columns of file A into a hash, then for each line of file B, loop through the hash keys, making the substitutions.
use strict; use warnings; my $fhi; my %data; open $fhi, '<', 'file_A.txt' or die "can not open file file_A.txt: $!" +; while (<$fhi>) { chomp; my @cols = split /\t/; $data{$cols[2]} = "@cols[2..3]"; } close $fhi; open $fhi, '<', 'file_B.txt' or die "can not open file file_B.t +xt: $!"; open my $fho, '>', 'file_B_out.txt' or die "can not open file file_B_o +ut.txt: $!"; while (<$fhi>) { for my $k (keys %data) { s/$k/$data{$k}/g; } print $fho $_; } close $fho;
One functional flaw with your solution is that you keep overwriting your output file every time you open it for output. Thus, you lose the results of your previous substitution.

Update: I like almut's $search string better than my for loop.

Replies are listed 'Best First'.
Re^2: Get data from a file to search and replace within a second file
by biscardi (Initiate) on Mar 23, 2010 at 15:48 UTC
    Dear all,

    thanks for your suggestions. I will need little bit to "digest" your suggestions.

    1. GrandFather: I have hard time telling apart your suggested code form some of the comments. I will try to disentangle the thing and get back to you.

    2. I tried the code from almut. It works but it will not distinguish between c1 and c11. In other words when C11 is found d1 is added within the 11. The final result is "c1 d11"

    3. I will take a look at toolic suggestion later

    Thanks for your help.

      2. I tried the code from almut. It works but it will not distinguish between c1 and c11. In other words when C11 is found d1 is added within the 11. The final result is "c1 d11"
      My solution also does not distinguish between c1 and c11. You can add \b anchors, as GrandFather has (see perlre):
      s/\b$k\b/$data{$k}/g;
        Unless c1 etc. are regular expressions, you'll want to use quotemeta. Here's a simple version that does more or less what you want, I think:
        my ($fa, $fb) = @ARGV; open IN, $fa or die $!; my %h; while (<IN>) { my ($str, $rep) = (split)[2,3]; $h{$str} = $rep; } my $pat = join '|', map { quotemeta $_ } keys %h; $pat = qr/\b($pat)\b/; print STDERR "$pat\n"; open IN, $fb or die $!; while (<IN>) { s/$pat/$1$h{$1}/g; print; }