繁体   English   中英

Bash / Shell:如何按列从csv文件中删除重复项?

[英]Bash/Shell: How to remove duplicates from csv file by columns?

我的csv与分开; 我需要删除第二列和第三列的内容不是唯一的行,并将材料传递到标准输出。

输入示例:

irrelevant;data1;data2;irrelevant;irrelevant  
irrelevant;data3;data4;irrelevant;irrelevant  
irrelevant;data5;data6;irrelevant;irrelevant  
irrelevant;data7;data8;irrelevant;irrelevant  
irrelevant;data1;data2;irrelevant;irrelevant  
irrelevant;data9;data0;irrelevant;irrelevant  
irrelevant;data1;data2;irrelevant;irrelevant  
irrelevant;data3;data4;irrelevant;irrelevant  

所需的输出

irrelevant;data5;data6;irrelevant;irrelevant  
irrelevant;data7;data8;irrelevant;irrelevant  
irrelevant;data9;data0;irrelevant;irrelevant  

我找到了仅将第一行打印到输出的解决方案:

sort -u -t ";" -k2,1 file  

但这还不够。

我尝试使用uniq -u但找不到仅检查几列的方法。

使用awk

awk -F';' '!seen[$2,$3]++{data[$2,$3]=$0}
      END{for (i in seen) if (seen[i]==1) print data[i]}' file
irrelevant;data5;data6;irrelevant;irrelevant
irrelevant;data7;data8;irrelevant;irrelevant
irrelevant;data9;data0;irrelevant;irrelevant

说明:如果在seen数组中不存在$2,$3组合,则将键为$2,$3的新条目存储在具有整个记录的data数组中。 每次找到$2,$3条目时, $2,$3的计数器都会增加$2,$3 然后最后打印那些counter==1条目。

如果顺序很重要,并且可以使用perl则:

perl -F";" -lane '
    $key = @F[1,2]; 
    $uniq{$key}++ or push @rec, [$key, $_] 
}{ 
    print $_->[1] for grep { $uniq{$_->[0]} == 1 } @rec' file
irrelevant;data5;data6;irrelevant;irrelevant  
irrelevant;data7;data8;irrelevant;irrelevant  
irrelevant;data9;data0;irrelevant;irrelevant  

我们使用column2和column3创建复合键。 我们通过将键和行按到第一次出现的行rec来创建array数组。

END块中,我们检查该事件是否是唯一的事件。 如果是这样,我们继续打印该行。

awk '!a[$0]++' file_input > file_output

这对我有用。 它比较整条线。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM