3

I have two files: s2.txt

14 3KC12828ACBA 
43 8DG59242BAAD 
25 8DG60566AAAF 
6 8DG60912AAAF

and pbas.txt:

3AG33662AAAC
3KC12828ACBA
8DG59242BAAD
8DG60349AAAC
8DG60565AAAG
8DG60566AAAF
8DG60568AAAC
8DG60912AAAF
8DG62635AAAC

Using bash on UNIX I want to join files in order to obtain one file like that:

3AG33662AAAC
3KC12828ACBA 14
8DG59242BAAD 43
8DG60349AAAC
8DG60565AAAG
8DG60566AAAF 25
8DG60568AAAC
8DG60912AAAF 6
8DG62635AAAC

How can make that?

10

That's what join does:

join -2 2 -a 1 pbas.txt s2.txt

The options say:

  • -2 2: the second file uses the second column to store the key
  • -a 1: output all lines from file 1, even if there's no match in file 2.
| improve this answer | |
  • @costica_p, please read unix.stackexchange.com/help/someone-answers – glenn jackman Feb 12 '17 at 19:06
  • Interesting is that not works for me because one of files have terminator line windows type (LF/CR) an other have unix type. After change to unix type for both files everything is perfect. – costica_p Feb 13 '17 at 13:12
2

AWK

It's fairly easy to achieve this in awk:

$ awk 'NR==FNR{a[$2]=$1; next}{print $1,a[$1]}' file1.txt file2.txt    
3AG33662AAAC
3KC12828ACBA 14
8DG59242BAAD 43
8DG60349AAAC
8DG60565AAAG
8DG60566AAAF 25
8DG60568AAAC
8DG60912AAAF 6
8DG62635AAAC

There's nothing special going on - this technique is frequently used by those who use awk frequently, especially when processing multiple files, and it is based on the idea of loading information from first file into array.

The way this works is simple. First using NR==FNR ( comparison between current processed line number and line number in current file) we read everything from file1.txt (in OP's example that's s2.txt ) into associative array of values. next keyword allows us to skip the next codeblock while we're still in the first file. Once we're out of the first file, the next codeblock will be executed, printing field 1 always, and corresponding item in array if it exists.

Perl

Using similar idea as the awk one, we can achieve similar result in Perl like so:

perl -lane 'if($F[1]){$hash{$F[1]}=$F[0]}else{print "$_ $hash{$_}"}' file1.txt file2.txt
| improve this answer | |

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.