![使用 CSV 解析器根据特定列对 CSV 行进行重复数据删除](https://linux22.com/image/220751/%E4%BD%BF%E7%94%A8%20CSV%20%E8%A7%A3%E6%9E%90%E5%99%A8%E6%A0%B9%E6%8D%AE%E7%89%B9%E5%AE%9A%E5%88%97%E5%AF%B9%20CSV%20%E8%A1%8C%E8%BF%9B%E8%A1%8C%E9%87%8D%E5%A4%8D%E6%95%B0%E6%8D%AE%E5%88%A0%E9%99%A4.png)
我搜索了这个任务,发现了以下较旧的问题:
但我无法使用,awk
因为我的数据是一个复杂的 CSV 文件,带有多个嵌套双引号。
假设我想对以下内容进行重复数据删除(简化情况):
Ref,xxx,zzz
ref1,"foo, bar, base",qux
ref1,"foo, bar, base",bar
ref2,aaa,bbb
在输出中我需要它如下:
Ref,xxx,zzz
ref1,"foo, bar, base",qux
ref2,aaa,bbb
没有awk
解决方案,只能使用任何 CSV 解析器。
我尝试了以下方法:
mlr --csv uniq -a -g Ref file.csv
但这是一个错误。
答案1
你可以跑
mlr --csv head -n 1 -g Ref input.csv
获取第一行分组依据Ref
答案2
Miller 的uniq
子命令返回唯一记录以及确定唯一性的字段。任何其他字段都将被丢弃。您收到错误是因为子命令的-a
(使用所有字段)和-g
(使用特定字段)选项不兼容。
仅使用米勒的一个好解决方案已经给出了。在现场分组时使用head
子命令 with可能是最方便的解决方案。-n 1
Ref
awk
您也可以让 Miller 使用( )中常用的相同类型的运算!seen[$1]++
,但由于 Miller 没有后置自增运算符,因此它会稍微长一些:
mlr --csv filter '@seen[$Ref] += 1; @seen[$Ref] == 1' file.csv
您还可以使用 Miller 将数据转换为 JSON,然后使用jq
执行unique_by()
操作,然后让 Miller 将数据转换回 CSV:
mlr --c2j cat file.csv | jq 'unique_by(.Ref)' | mlr --j2c cat