Unix环境下CSV文件去重:保留最新时间记录的命令实现
解决方法:用
sort + awk组合实现 要实现保留每个ID+NAME组中最新TIME的记录,Unix下可以用sort和awk的组合命令高效处理这个需求,具体命令如下:
sort -t',' -k1,2 -k3,3r your_input.csv | awk -F',' '!seen[$1$2]++' > your_output.csv
命令分解说明:
sort排序阶段-t',':指定CSV的分隔符为逗号-k1,2:先按第1列(ID)和第2列(NAME)升序排序,把同一组的记录集中在一起-k3,3r:对同一组内的记录,按第3列(TIME)降序排列,让每个组里时间最新的记录排在最前面
awk去重阶段-F',':同样指定逗号为分隔符!seen[$1$2]++:用$1$2(ID和NAME的拼接)作为组的唯一标识,seen是一个关联数组,用来标记该组是否已输出。第一次遇到某个组时,seen[$1$2]为0,!0为真,输出当前行;后续再遇到同一组的记录时,seen[$1$2]已大于0,条件为假,直接跳过。
验证结果
用你的输入数据测试,执行命令后会得到你需要的输出:
"ID","NAME","TIME" "858","abc","21:38:52" "978","def","21:38:52" "874","ghi","18:20:33" "319","ghi","22:29:16"
补充:保持原始组顺序的方案
如果需要严格按照原始数据中各组首次出现的顺序输出结果,可以用下面的awk命令(无需提前排序):
awk -F',' ' NR == 1 {print; next} { key = $1$2 if (! (key in max_time) || $3 > max_time[key]) { max_time[key] = $3 record[key] = $0 if (!(key in order)) order[++count] = key } } END { for (i=1; i<=count; i++) print record[order[i]] } ' your_input.csv > your_output.csv
这个命令会先遍历所有记录,为每个组保存最新时间对应的行,同时记录各组首次出现的顺序,最后按该顺序输出结果。
内容的提问来源于stack exchange,提问作者user9019741
相关产品推荐
相关产品推荐

