csv删除一列中具有重复值的所有行

时间:2017-03-03 17:31:00

标签: linux shell csv

example1.csv

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"

需要删除column1中具有重复值的行,输出如下

必需输出

example1_out.csv

id2, value2
id3, value3

example2_out.csv

"06e04,0429","405872,8637110"
"06e04,0430","405872,8637110"
"06e04,0431","405872,8637111"

有一些解决方案可以删除重复记录,这些记录会保留其中一个重复记录,例如此SO question。但是,在这种情况下,需要从输出中排除具有column1重复值的所有行。

4 个答案:

答案 0 :(得分:1)

cut -f1 -d, somecsv.csv | sort | uniq -u | grep -Ff- somecsv.csv

第一个命令从输入中提取第一列。第二个命令对id进行排序,因此下一个命令只能列出唯一的命令。最终grep获取唯一ID并在输入文件中搜索它们。

答案 1 :(得分: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"

答案 2 :(得分:1)

这是一个较短的awk选项。

awk -F, 'NR==FNR{a[$1]++;next} a[$1]<2' file.csv file.csv

这两次读取文件 - 一次填充第一个字段的计数器数组,第二次打印计数小于2的行。

如果您更喜欢在纯shell而不是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

同样,这是两个步骤 - 第一个填充计数器数组,第二个步骤遍历文件并打印相应的行。

答案 3 :(得分:0)

您可以使用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数组

保留
相关问题