web-dev-qa-db-ja.com

フィールド番号が異なる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を使用して、次のような1つのファイルを取得するためにファイルを結合したいと思います。

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

どうすればそれを作ることができますか?

3
costica_p

それがjoinが行うことです。

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

オプションは言う:

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

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が常に出力され、対応するアイテムが存在する場合は配列に出力されます。

Perl

Awkと同様のアイデアを使用すると、Perlで次のように同様の結果を得ることができます。

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