私は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
どうすればそれを作ることができますか?
それがjoin
が行うことです。
join -2 2 -a 1 pbas.txt s2.txt
オプションは言う:
-2 2
:2番目のファイルは2番目の列を使用してキーを格納します-a 1
:ファイル2に一致するものがない場合でも、ファイル1からすべての行を出力します。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