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

时间:2013-09-04 10:31:44

标签: bash parsing csv

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

以下是我从他们那里收到的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行永远不应该由供应商创建,bug已经存在 供应商承认并承诺修复,但我不希望它很快。

我需要解析和修改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

但是现在我想不出再添加第二列的方法,所以我认为这不会有所帮助。

2 个答案:

答案 0 :(得分:1)

这个怎么样?

$ 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是列。

答案 1 :(得分:0)

如果您希望除了一列之外的所有列都基于比较重复条目时,只需在每个循环中删除它并重新评估$ 0,同时将$ 0保存到其前的另一个值。

awk -F, -v i=2 '{t=$0;$i=""}!a[$0]++{print t}' file

其中i设置为要忽略的列数。

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