CSV删除与重复的值的所有行中的一列
example1.csvCSV删除与重复的值的所有行中的一列
id1, value1
id2, value2
id3, value3
id1, value4
example2.csv
"06e04,0428","405872,8637110"
"06e04,0428","405872,8637111"
"06e04,0429","405872,8637110"
"06e04,0430","405872,8637110"
"06e04,0431","405872,8637111"
需要删除与在列1重复的值的行,以输出如下
需要输出
example1_out。 CSV
id2, value2
id3, value3
example2_out.csv
"06e04,0429","405872,8637110"
"06e04,0430","405872,8637110"
"06e04,0431","405872,8637111"
有解决方案,以除去保留的重复记录一个在本SO question重复记录。但是在这种情况下,需要从输出中排除列1具有重复值的所有行。
这awk
可以做,在一个命令:
awk -F, '{arr[$1]=$0} seen[$1]++{delete arr[$1]} END{for (i in arr) print arr[i]}' file.csv
id2, value2
id3, value3
为您编辑的问题使用:
awk -F'","' '{arr[$1]=$0} seen[$1]++{delete arr[$1]} END{for (i in arr) print arr[i]}' file.csv
"06e04,0429","405872,8637110"
"06e04,0430","405872,8637110"
"06e04,0431","405872,8637111"
请注意,这不会保留行顺序'id3,value3 id2,value2' –
当列1的值为','时,这不起作用 - 请参阅更新的问题。 – user3206440
我已根据您编辑的问题修改了我的答案。检查给出预期输出的更新答案。 – anubhava
您可以使用awk
:
awk -F "," '{
if (length(arr[$1]) == 0){
arr[$1]=$0
order[i++]=$1
}
else{
delete arr[$1]
}
}
END {
for (i = 1; i < length(order); i++) {
print arr[order[i]]
}
}' somecsv.csv
它存储阵列中的所有项目,如果它发现两次删除该项目。顺序将予以保留一个额外order
阵列
这里有一个较短的awk选项。
awk -F, 'NR==FNR{a[$1]++;next} a[$1]<2' file.csv file.csv
这读取文件两次 - 一次来填充第一场的计数器阵列,并且第二次打印其计数小于2
如果您更愿意线为此在纯壳,而不是awk和你的shell是bash
,你可以像这样的东西得到了类似的功能:
$ declare -A a=()
$ while IFS=, read f _; do ((a[$f]++)); done < file.csv
$ declare -p a
declare -A a=([id1]="2" [id3]="1" [id2]="1")
$ while IFS=, read f1 f2; do [ "${a[$f1]}" -lt 2 ] && printf '%s,%s\n' "$f1" "$f2"; done < file.csv
id2, value2
id3, value3
再次,这是两个步骤 - 填充计数器阵列第一,第二步通过文件和打印approp划线。
你已经标记了你的问题'shell'。你是不是指'bash'? – ghoti
@Grzesiek - 你能否添加nodejs答案? – user3206440
@ user3206440我很抱歉使用awk的选定解决方案更短。 – Grzesiek