在 shell 脚本中比较 csv 的特定列

问题描述 投票:0回答:2

我有两个想要比较的 CSV 文件。第一个看起来像:

aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
bbbbbbbb-f76a-4a05-bb53-63aba9d03fe2,5678
cccccccc-e351-4d8e-b44a-080f6ccdef7d,9012

第二个看起来像(只有一个字段):

bbbbbbbb-f76a-4a05-bb53-63aba9d03fe2
cccccccc-e351-4d8e-b44a-080f6ccdef7d

我想根据 UUID 比较(使用

comm
等 shell 命令)这两个集合,显示第一个文件中的完整行以及第二个文件中未出现的 UUID。 因此,对于示例数据如上所述,输出应该是

aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
如果我只有两个 UUID 列表,我可以轻松地与 

comm

 进行比较,但我不知道如何处理额外的字段。我想我可以切断第二个字段,
comm
,然后循环遍历结果并在原始的双字段集中进行 grep,但这似乎有点低效。使用标准实用程序有更好的方法吗?我也看到了
这个问题,但这似乎丢弃了不常见的行/字段。

bash shell csv awk sh
2个回答
3
投票
您可以将 grep 与第二个文件一起使用作为您不想匹配的固定字符串:

$ grep -Fvf second.csv first.csv aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
或者使用第一个字段连接但抑制连接的输出线:

$ join -t, -v1 <(sort -k1 -t, first.csv) <(sort second.csv) aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
    

1
投票
如果

awk

 是一个选项,您可以使用它首先将第二个文件的所有行作为键读取到数组中,然后通过这些数组键中第一列的包含性来过滤第一个文件。请注意文件的顺序。

awk -F, 'NR==FNR {a[$0]; next} !($1 in a)' file2.csv file1.csv
aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
    
© www.soinside.com 2019 - 2024. All rights reserved.