Bash 在csv文件上运行uniq忽略文件中保留最高值的列

Bash 在csv文件上运行uniq忽略文件中保留最高值的列,bash,parsing,csv,Bash,Parsing,Csv,我使用的数据供应商有一个bug,需要很长时间才能修复 以下是我从他们那里收到的csv文件的简化版本: # cat new_data20130904.csv a,001,b,c,d e,002,f,g,h e,003,f,g,h i,004,j,k,l 第2行和第3行的第2列是唯一的,但数据相同 第3行不应该由供应商创建,错误已经被删除 供应商已确认并承诺修复,但我不希望很快修复 我需要解析和修改CSV文件,使其成为: a,001,b,c,d e,002,f,g,h i,004,j,k,l 我

我使用的数据供应商有一个bug,需要很长时间才能修复

以下是我从他们那里收到的csv文件的简化版本:

# cat new_data20130904.csv
a,001,b,c,d
e,002,f,g,h
e,003,f,g,h
i,004,j,k,l
第2行和第3行的第2列是唯一的,但数据相同

第3行不应该由供应商创建,错误已经被删除 供应商已确认并承诺修复,但我不希望很快修复

我需要解析和修改CSV文件,使其成为:

a,001,b,c,d
e,002,f,g,h
i,004,j,k,l
我想编写一些防御性的代码来删除这些错误重复的行

理想情况下,我想使用Ubuntu/Debian内置

最初,我认为删除第二个字段并运行uniq会 这是一个良好的开端:

# cut -d, -f1,3- new_data20130904.csv | uniq
a,b,c,d
e,f,g,h
i,j,k,l
但是现在我想不出一个办法把第二列加回去,所以我认为这不会有什么帮助。

这个怎么样

$ awk -F, '{if (a[$1]) next}a[$1]=$0' file
a,001,b,c,d
e,002,f,g,h
i,004,j,k,l
解释 我们将第一列存储在数组中。如果它已经在数组中,我们将跳过该记录

  • -F,
    将字段分隔符设置为逗号
  • {if(a[$1])next}
    如果第一个字段已经在数组中,请跳过
  • a[$1]=$0
    将第一个字段保存为数组的键
    a
    并打印行(
    print$0
    是awk的默认行为,因此不需要写入)
如果它是需要修改的第n列,我将如何调整它 忽视


您可以将
a[$1]
替换为
a[$n]
,其中
n
是列。

如果您希望在比较重复条目时基于除一列以外的所有列,只需在每个循环中删除它,并重新计算$0,同时将$0保存为前面的另一个值

awk -F, -v i=2 '{t=$0;$i=""}!a[$0]++{print t}' file
其中,
i
设置为要忽略的列数


中![$0]+
$0
已经是一个重新计算过的表单,
$i
已经为空,并且它将密钥存储在
a
中。如果尚未存储,则值应为初始值
0
将导致它被否定为
1
<代码>++将在重新评估后增加它。如果最初看到它,它将是
0
(否定为
1
),它将导致执行下一个命令,即打印该行。在重复的条目中,它已经被递增,并将反回到
0
,这将不允许执行下一个命令。

Awesome,这在我给出的示例中有效,谢谢。你能解释一下它是怎么做的吗?如果第n列需要忽略,我将如何调整它?