同じ形式の2つの入力ファイルの最初の列を比較しようとしています。形式は次のとおりです。
FILE1:
0000abc5abc3 GR096
0000def5ae87 GR001
0000cab5aea3 GR001
0000bac5aeeb GR001
0000fed5af13 GR001
0000efd5b16f GR001
0000cba5b187 GR001
0000bca5b2a3 GR001
FILE2:
0000abc5abc3 GR097
0000def5ae87 GR001
0000cab5aea3 GR001
0000bac5aeeb GR001
0000fed5af13 GR123
0000cba5b187 GR169
列 1 には、FILE1 および FILE2 の MAC アドレスが含まれます。 FILE1の1列の値をFILE2の1列と比較して一致する項目があれば、FILE1の1列と2列の値とFILE2の2列の値が3つの列で出力されるようにしたいと思います。
DESIRED OUTPUT:
0000abc5abc3 GR096 GR097
0000def5ae87 GR001 GR001
0000cba5b187 GR001 GR169
各ファイルには何百万ものエントリが含まれています。 whileループを使用してbashで入力を実行することは、各項目を繰り返すため、常に遅くて非効率的です。
while read -r mac1 code1; do
while read -r mac2 code2 ; do
if [ "$mac1" == "$mac2" ]; then
printf "%s %s %s\n" "$mac1" "$code1" "$code2"
fi
done < "$FILE1"
done < "$FILE2" > OUTPUTFILE
配列を使用するとAwkははるかに高速ですが、次の構文を使用すると、FILE2の2番目の列を出力の3番目の列に印刷することはできません。この構文は、列2のみ2番目に印刷します。
awk 'NR==FNR { n[$1] = $1; n[$2] = $2; next } ($1 in n) { print n[$1],n[$2],$2 }'
私はAWKを好むが、bashでそれほど速く走っていれば大丈夫でしょう。
要約:file1の1列の値がfile2で見つかった場合は、1列、2列(ファイル1)、2列(ファイル2)の値を出力します。
答え1
出力をソートできる場合:
join <(sort file1.txt) <(sort file2.txt)
答え2
awk を修正するには:
awk 'NR==FNR { n[$1]=$0;next } ($1 in n) { print n[$1],$2 }' file1 file2
#Output:
0000abc5abc3 GR096 GR097
0000def5ae87 GR001 GR001
0000cab5aea3 GR001 GR001
0000bac5aeeb GR001 GR001
0000fed5af13 GR001 GR123
0000cba5b187 GR001 GR169
答え3
join
これを行うのに適したツールは次のとおりです。
join <(sort file1) <(sort file2)
ソートされたファイルで動作するため、bashのプロセス置換(<(...)
)を使用して各ファイルをjoin
。