AWK 比较两个文件中的列 1 打印附加列到输出中的第三个

AWK 比较两个文件中的列 1 打印附加列到输出中的第三个

想要比较具有相同格式的两个输入文件的第一列。格式如下所示:

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.

相关内容