2017-03-03 122 views
0

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具有重複值的所有行。

+0

你已經標記了你的問題'shell'。你是不是指'bash'? – ghoti

+0

@Grzesiek - 你能否添加nodejs答案? – user3206440

+0

@ user3206440我很抱歉使用awk的選定解決方案更短。 – Grzesiek

回答

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

請注意,這不會保留行順序'id3,value3 id2,value2' –

+0

當列1的值爲','時,這不起作用 - 請參閱更新的問題。 – user3206440

+0

我已根據您編輯的問題修改了我的答案。檢查給出預期輸出的更新答案。 – anubhava

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

第一條命令從輸入中提取第一列。第二個命令對ID進行排序,因此下一個命令只能列出唯一的ID。最後的grep將採用唯一的ID並在輸入文件中搜索它們。

+0

嗯......這也會匹配col1中的文本包含在其他colums中的行......例如,'id1,valid2' – jm666

+1

因此,將'grep -Ff -'改爲'sed's/^/^ /'| grep -f-'。同樣,如果第一列包含特殊字符,它可能會中斷... – choroba

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陣列

1

這裏有一個較短的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劃線。

相關問題