Hi All, I need a perl script to generate the following

Replace value in a column of one file with a value from second file

File1

    246   0.668  20.644  20.610   0.000 3 U   1.039e+03  0.000E+00 - 0  1673  1676  1663  1662
     18   0.816  22.786  24.906   0.000 3 U   1.815e+03  0.000E+00 - 0  1760  1761  1743  1744
    248   0.816  22.786  24.906   0.000 3 U   1.856e+03  0.000E+00 - 0  1760  1761  1763  1764

File2

1681   1.035 0.000 HD2    86
1744  22.256 0.000 CD2    86
1662  25.318 0.000 CD1    86
1685  26.309 0.000 CG     86

Column 15 in first file should find a match in column 1 of file2. Then column 4 in file1 should be replaced by value from column 2 of file2

Output should be like this

     13   0.668  20.644  20.610   1.035 3 U   5.118e+02  0.000E+00 - 0  1659  1658  1680  1681
    246   0.668  20.644  20.610  25.318 3 U   1.039e+03  0.000E+00 - 0  1673  1676  1663  1662

Thanks in advance

Surya

Edited 2 Years Ago by Dani: Formatting fixed

Hi,

In solivng this type of problems, you have to open your two files, read from the second one and take the first two column as key/value for an hash.
Then open the first file and read line by line and check if the last column is the same as the key of your hash. If so, replace the 4th Column of the present line from the first file with the value of the matched key and print out. It is that easy.

That is all about it. But here is a code that works, of course you can adopt it. But if you don't have the non-core module like Inline::Files, the code might not work.

EVen if you don't have the named module, you can simply use open function from Perl to open your two files and there will be no need for the module at all.

use warnings;
use strict;
use Inline::Files;

my %in_file2;  # use an hash

while (<FILE2>) {
    my ( $key, $value ) = ( split /\s+/, $_ )[ 0, 1 ];
    $in_file2{$key} = $value;
}

while (<FILE1>) {
    my @data = split /\s+/, $_;
    if ( $in_file2{ $data[-1] } ) {
        # Change the 4th column if the last one is the same
        $data[4] = $in_file2{ $data[-1] };
        # join it together again and print
        print join( "\t" => @data ), $/;
    }
}


__FILE1__
246   0.668  20.644  20.610   0.000 3 U   1.039e+03  0.000E+00 - 0  1673  1676  1663  1662
18   0.816  22.786  24.906   0.000 3 U   1.815e+03  0.000E+00 - 0  1760  1761  1743  1744
248   0.816  22.786  24.906   0.000 3 U   1.856e+03  0.000E+00 - 0  1760  1761  1763  1764
__FILE2__
1681   1.035 0.000 HD2    86
1744  22.256 0.000 CD2    86
1662  25.318 0.000 CD1    86
1685  26.309 0.000 CG     86

Output generated is thus:

246 0.668   20.644  20.610  25.318  3   U   1.039e+03   0.000E+00   -   0   1673    1676    1663    1662
18  0.816   22.786  24.906  22.256  3   U   1.815e+03   0.000E+00   -   0   1760    1761    1743    1744

Hope this helps.

Edited 2 Years Ago by 2teez

Marking this question solved. Please mark questions solved in the future to give credit where credit is due :)

This question has already been answered. Start a new discussion instead.