フィールド番号の異なる2つのファイルの組み合わせ

フィールド番号の異なる2つのファイルの組み合わせ

2つのファイルがあります:s2.txt

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

そしてpbas.txt:

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

UNIXでは、bashを使用してファイルを結合して次のファイルを取得したいと思います。

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

どうすればいいですか?

答え1

これはjoin

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

オプションは次のように言います。

  • -2 2:2番目のファイルは2番目の列を使用してキーを保存します。
  • -a 1: ファイル 2 に一致する項目がない場合でも、ファイル 1 のすべての行を出力します。

答え2

AWK

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

カラフルなものはありません。この技術は、awk定期的に作業する人、特に複数のファイルを扱うときによく使用され、最初のファイルの情報を配列にロードするというアイデアに基づいています。

仕組みは簡単です。まずNR==FNR、(現在処理されている行番号と現在のファイルの行番号との比較)を使用してfile1.txt(OPの例ではs2.txt)すべてを関連値の配列として読み込みます。 nextキーワードを使用すると、最初のファイルから次のコードブロックをスキップできます。最初のファイルを終了すると、次のコードブロックが実行され、常にフィールド1を印刷し、配列にそのエントリがある場合は印刷します。

真珠

awkに似たアイデアを使用すると、Perlでも次のような同様の結果が得られます。

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

関連情報