次の2つのファイルをマージしたい2つの列の一致に基づいて2つのファイルをマージする方法は?ただし、1つのファイルにすべての結果が含まれているとは限りません。例えば
ファイル1
1 dog
2 cat
3 fox
4 cow
ファイル2
1 woof
2 meow
4 mooh
希望の出力
1 dog woof
2 cat meow
3 fox
4 cow mooh
ベストアンサー1
配列の配列を処理するには、GNU awkを使用します。
$ awk '{a[$1][(NR>FNR)]=$2} END{for (i in a) print i, a[i][0], a[i][1]}' file{1,2}
1 dog woof
2 cat meow
3 fox
4 cow mooh
または awk を使用してください。
$ awk '{keys[$1]; a[$1,(NR>FNR)]=$2} END{for (i in keys) print i, a[i,0], a[i,1]}' file{1,2}
1 dog woof
2 cat meow
3 fox
4 cow mooh
上記の出力は最初のフィールドの数値の昇順ですが、これは幸運/偶然です。出力行の順序は、実際には「in」演算子によって提供される「ランダム」(通常はハッシュ順序)です。興味がある場合は、出力をパイプで接続しますsort -k1,1n
(またはPROCINFO["sorted_in"]="@ind_num_asc"
GNU awkのENDセクションの先頭に設定します)。
このソリューションとソリューションの重要な違いは次のとおりjoin
です。
- これは、入力がソートされず、
join
キーフィールドで入力をソートする必要がある場合にも機能します。 - file2にfile1にないキーを持つ行がある場合(またはその逆の場合)、add
-a2
tojoin
コマンドとは異なり、その一意の行がどのファイルから来たのかがわかるように表示します。
以下は、テストのためのより包括的な入力/出力の例です。
$ head file{1,2}
==> file1 <==
1 dog
2 cat
4 cow
5 bear
==> file2 <==
1 woof
2 meow
3 growl
4 mooh
その後、上記のawkスクリプトを実行して同じ出力を取得できます。
$ awk '{a[$1][(NR>FNR)]=$2} END{for (i in a) print i, a[i][0], a[i][1]}' file{1,2}
1 dog woof
2 cat meow
3 growl
4 cow mooh
5 bear
そして3 growl
、前に余分なスペースがあるので、growl
これがfile2の唯一の縮小であることがわかりますjoin
。代わりに、以下を使用してください。
$ join -a1 -a2 file1 file2
1 dog woof
2 cat meow
3 growl
4 cow mooh
5 bear
file1の一意の行(例:)5 bear
とfile2の一意の行(例3 growl
)を区別することはできません。