想要比较具有相同格式的两个输入文件的第一列。格式如下所示:
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 列的值作为第三列。
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 列:
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
.