使用 awk 在匹配的列值上加入 2 个文件

joining 2 files on matching column values using awk

我知道已经发布了类似的问题,但我在使用 awk FNR==NR 获得我想要的输出时仍然遇到了一些麻烦... 我有 2 个这样的文件

File 1: 
123|this|is|good
456|this|is|better
...

File 2:
aaa|123
bbb|456
...

所以我想加入文件 2/column2 到文件 1/column1 和输出文件 1(第 2、3、4 列)和文件 2(第 1 列)的值。

提前致谢。

使用 awk 你可以做类似的事情

awk -F \| 'BEGIN { OFS = FS } NR == FNR { val[] = ; next }  in val { $(NF + 1) = val[]; print }' file2 file1

NF是一条记录的字段数(默认为行),所以$NF是最后一个字段,$(NF + 1)是后面的字段。通过将传递 file2 中保存的值分配给它,一个新字段会在打印前附加到记录中。

需要注意的一件事:这类似于内部连接,即仅打印其键出现在两个文件中的记录。要使其成为正确的连接,您可以使用

awk -F \| 'BEGIN { OFS = FS } NR == FNR { val[] = ; next } { $(NF + 1) = val[]; print }' file2 file1

也就是说,您可以在追加和打印操作中删除 in val 条件。如果 </code> 不在 <code>val 中,val[] 为空,打印前将在记录中附加一个空字段。

但使用 join 可能更好:

join -1 1 -2 2 -t \| file1 file2

如果您不希望关键字段成为输出的一部分,请通过 cut -d \| -f 2- 将这些命令中的任何一个的输出通过管道传输以摆脱它,即

join -1 1 -2 2 -t \| file1 file2 | cut -d \| -f 2-

如果文件的行数相同且顺序相同,则

paste -d '|' file1 file2 | cut -d '|' -f 2-5
this|is|good|aaa
this|is|better|bbb

我在对 Wintermute 的回答的评论中看到文件未排序。使用 bash,进程替换可以方便地即时排序:

paste -d '|' <(sort -t '|' -k 1,1 file1) <(sort -t '|' -k 2,2 file2) |
cut -d '|' -f 2-5

重申一下:这个解决方案需要文件之间一一对应