使用 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
重申一下:这个解决方案需要文件之间一一对应
我知道已经发布了类似的问题,但我在使用 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
重申一下:这个解决方案需要文件之间一一对应