0

I have two files:

>head(fileA)
   2    1   544.8  1279.2   1.0603  3.2460  0.0542 
   3    1   546.2  1277.8   1.0463  3.2460  0.0553 
   3    2   543.9  1280.1   0.1652  3.2460  0.0177 
   4    1   543.7  1280.3   1.0819  3.2460  0.0527 
>head(fileB)
1 Coly
2 Mony
3 Fong
4 Wow
5 Poly

I would like to assign the names in fileB to the number in fileA, to get the following output

   2 Mony   1 Coly   544.8  1279.2   1.0603  3.2460  0.0542 
   3 Fong   1 Coly  546.2  1277.8   1.0463  3.2460  0.0553 
   3 Fong   2 Mony  543.9  1280.1   0.1652  3.2460  0.0177 
   4 Wow    1 Coly   543.7  1280.3   1.0819  3.2460  0.0527 

To be honest I was not able to try anything, I just spent a lot of time looking up how to do this. The only thing that I thought about was to assign the numbers in fileA to variables and then every time this variables are found append to it the content of fileB. Unfortunately, I do not know how to do this.

Any suggestion, link, directive? Thanks

  • The only reasonable solution I see is to use a full scripting language, like Python or Perl. – vonbrand Feb 14 '16 at 22:15
1

You can use bash's read, and grep and tr:

cat fileA | while read i j k ; do
  grep "^$i\W" fileB | tr '\n' ' '
  grep "^$j\W" fileB | tr '\n' ' ' 
  echo $k 
done
  • wow that is great! Would you mind to explain it a bit? – efrem Feb 15 '16 at 9:33
  • I tried now on another file, but it seems to mess up all the results when there are number >9, meaning with two character. Any idea how to fix this? – efrem Feb 15 '16 at 16:49
  • Ah, right, forgot about that. Need to use this instead: grep "^$i\W" fileB and etc – user100375 Feb 15 '16 at 17:08
  • To explain a bit: cat fileA | while read i j k will take in lines from fileA one at a time, and split them on spaces into the i (first column, space delimited), j (second column) and k (remainder). Then grep for $i searches for that pattern (in my edit, it now searches for the whole word $i at the beginning of the line, not just a partial match) in fileB, and the tr will replace the trailing newline with a space. Repeat this for $j, and then the echo $k prints the rest of the line (now including the trailing newline). – user100375 Feb 15 '16 at 17:17
  • thanks very much, but it still mess up quite a bit, I have multiple entry fileB in the line of interest in filA. – efrem Feb 15 '16 at 17:44
0

Perl to the rescue!

#! /usr/bin/perl
use warnings;
use strict;

open my $B, '<', 'B' or die $!;
my %name_of;
while (<$B>) {
    my ($num, $name) = split;
    $name_of{$num} = $name;
}

open my $A, '<', 'A' or die $!;
while (<$A>) {
    my @F = split;
    splice @F, 2, 0, $name_of{ $F[1] };
    splice @F, 1, 0, $name_of{ $F[0] };
    print "@F\n";
}

The second paragraph reads the B file into a hash table, mapping numbers to names. The third paragraph reads the A file, splits each line into an array, inserts the names retrieved from the hash table according to the first two columns into the array, and prints it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.