如何保留未排序CSV文件中Field1的最后一条重复记录?
需求:保留CSV中Field1重复值的最后一条记录
我有一个未排序的CSV文件,包含6个字段,Field1存在重复值,需要保留每个Field1值对应的最后一条记录,删除其他重复项。试过awk -F',' '!seen[$1]++',但这个命令会保留第一条重复记录,不符合需求,求其他解决方法。
示例数据:
17710813,24759, 17722388,47281,,,, 17722388,1999084,0246,car,28-Jul-11, 17722388,1159769,11301,earn,16-Jun-16, 17722388,136787,35451,dress,,15-Jun-16 17732315,242393,,light,28-Aug-05,21-Jul-08
预期输出:
17710813,24759, 17722388,136787,35451,dress,,15-Jun-16 17732315,242393,,light,28-Aug-05,21-Jul-08
解决方法
方法1:缓存记录后输出
用awk把每条记录按Field1存进数组,后面的记录自动覆盖前面的,最后遍历数组输出所有结果:
awk -F',' '{seen[$1] = $0} END {for (key in seen) print seen[key]}' your_file.csv
逻辑很直接:每读一行就用Field1当键,把整行内容存到数组里,同Field1的新记录会直接替换旧的,最后处理完所有行后,把数组里的内容全部打印出来,就是每个Field1对应的最后一条记录。
方法2:反向处理(适合大文件)
如果文件太大,缓存所有记录占内存,可以用tac反转文件后再处理:
tac your_file.csv | awk -F',' '!seen[$1]++' | tac
步骤拆解:
tac把文件行反转,原文件的最后一条变成第一条- 用你熟悉的
!seen[$1]++保留反转后每个Field1的第一条(也就是原文件的最后一条) - 再用
tac把结果反转回来,恢复原来的顺序
特殊情况处理
如果你的CSV字段里有带引号的逗号(比如"hello,world",123),直接用-F','分割会出错,这时可以用专门的CSV工具csvkit:
csvcut -c 1 your_file.csv | nl -ba | sort -k2,2 -k1,1nr | sort -k2,2 -u | cut -f1 | sort | xargs sed -n '{}p' your_file.csv
不过这个方法复杂度高,只有遇到复杂CSV格式时才需要用。
内容的提问来源于stack exchange,提问作者victory
相关产品推荐
相关产品推荐

