如何对文件指定列去重并统计唯一行数?解决地址含逗号导致常规命令失效的问题
问题分析
你用的两个命令失效的原因其实很好理解:
sort -u -t, -k1,1 file:sort -u是看整行内容是否重复,而不是只看name列。哪怕两条记录name一样,只要其他字段不同,它就不会去重,所以这个命令根本没法实现按name去重的需求。awk -F"," '!_[$1]++' file:这个命令本身其实能拿到第一个逗号前的name,但它会把表头也保留下来,而且如果你的数据里name前后有空格(比如格式不严谨的情况),可能会把Smith和Smith当成不同的name;另外你还需要输出唯一行数,这个命令也做不到。
因为你的CSV里address字段带逗号,但name字段本身是没有逗号的,所以我们可以直接提取第一个逗号前的内容作为去重的依据,同时处理表头和计数的需求。
解决方案
试试这个awk命令,它会跳过表头,只保留每个name第一次出现的记录,最后还会输出唯一name的数量:
awk -F',' ' NR == 1 {next} # 跳过表头行 { # 提取name并去掉前后可能的空格,避免格式问题导致误判 name = $1 gsub(/^[[:space:]]+|[[:space:]]+$/, "", name) if (!seen[name]++) { print # 打印第一次出现的记录 count++ } } END {print count} # 最后输出唯一name的数量 ' your_file.csv
效果验证
运行这个命令后,会先输出你想要的三条去重记录:
Smith, 18, 201392, 19 Rand Street, USA Dan, 19, 029123, 23 Lambert Rd, Australia Kyle, 25, 245123, 103 Orange Rd, UK
然后在下一行输出3,完全符合你的预期。
额外说明
如果以后你的name字段也可能包含逗号(这种情况规范的CSV会用双引号把含逗号的字段包起来),可以用专门的CSV工具csvkit来处理:
- 先安装
csvkit(比如用sudo apt install csvkit或者pip install csvkit) - 用下面的命令去重并计数:
csvcut -c name,age,id,address your_file.csv | csvsort -c name | csvuniq -c name -d | tail -n +2 | tee >(wc -l)
不过这个方案要求你的CSV必须符合标准格式(含逗号的字段用双引号包裹),否则会解析出错哦。
内容的提问来源于stack exchange,提问作者quickhelp
相关产品推荐
相关产品推荐

