用Shell工具对比两个CSV文件,找出首文件独有的UUID完整行
需求与解决方案
问题背景
有两个CSV文件需要对比:
- 第一个文件包含两列数据,格式如下:
aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234 bbbbbbbb-f76a-4a05-bb53-63aba9d03fe2,5678 cccccccc-e351-4d8e-b44a-080f6ccdef7d,9012
- 第二个文件仅包含一列UUID数据,格式如下:
bbbbbbbb-f76a-4a05-bb53-63aba9d03fe2 cccccccc-e351-4d8e-b44a-080f6ccdef7d
需求
执行脚本 myscript file1.csv file2.csv 后,输出第一个文件中UUID未出现在第二个文件中的完整行,预期输出:
aaaaaaaa-fb34-4e3e-aed5-eec78d02d59b,1234
现有思路的问题
仅对比UUID列表用 comm 即可,但无法直接处理第一个文件的额外字段;尝试过先截取首列用 comm 对比,再循环结果去原文件 grep,但这种方式效率极低。
最优方案:使用awk实现
用awk可以一次性完成对比,仅需遍历两个文件各一次,效率远高于循环grep。
脚本实现
将以下内容保存为myscript:
#!/bin/bash awk -F ',' 'NR==FNR {uuid[$1]; next} !($1 in uuid)' "$2" "$1"
脚本解释
-F ',':指定逗号为字段分隔符,方便提取第一个文件的首列UUIDNR==FNR:处理第一个输入文件(即脚本参数中的file2.csv)时,把每行的UUID存入数组uuid的键中next:跳过后续逻辑,直接处理下一行!($1 in uuid):处理第二个输入文件(即脚本参数中的file1.csv)时,判断当前行首列UUID是否不在uuid数组中,若是则输出整行
执行步骤
- 给脚本添加执行权限:
chmod +x myscript
- 运行脚本:
./myscript file1.csv file2.csv
效率优势
awk的处理逻辑是O(n+m)(n、m分别为两个文件的行数),仅需扫描两个文件各一次;而循环grep的逻辑是O(k*m)(k为差异UUID的数量),当文件规模较大时,两者效率差距会非常明显。
内容的提问来源于stack exchange,提问作者tsj
相关产品推荐
相关产品推荐

