【问题标题】:Remove duplicates based on specific column根据特定列删除重复项
【发布时间】:2017-11-26 00:40:53
【问题描述】:

我的 Linux CentOS 7 上确实有一个以下格式的大文本文件。

430004, 331108, 075, 11, 19, Chunsuttiwat Nattika
431272, 331108, 075, 11, 19, Chunsuttiwat Nattika
435979, 335086, 803, 6, 19, ANNI BRENDA
436143, 335151, 545, 4, 23, Agrawal Abhishek
436723, 335387, 386, 2, 19, Bhati Naintara
438141, 325426, 145, 11, 19, Teh Joshua

如果与第二列匹配,我想删除包括原点在内的重复行。

预期输出:

435979, 335086, 803, 6, 19, ANNI BRENDA
436143, 335151, 545, 4, 23, Agrawal Abhishek
436723, 335387, 386, 2, 19, Bhati Naintara
438141, 325426, 145, 11, 19, Teh Joshua

【问题讨论】:

  • 如果重复项彼此相邻,如示例所示,那么最好使用的工具是uniq...查看man uniq 几分钟,你就可以做到它
  • @αԋɱҽԃαмєяιcαη,你的文件有多大?显示wc -l yourfile
  • 那么,您可以先对其进行排序,然后应用 uniq 命令。在这两种情况下,您都可以跳过第一列...假设您在, 之后确实有这些空格@
  • 那么,根据 tow 列中的值,您想删除带有重复 原点的行吗?
  • 我猜你不需要任何人的帮助..

标签: regex linux text awk sed


【解决方案1】:

更新

排序 + uniq + awk管道:

sort -k2,2 file | uniq -f1 -c -w7 | awk '$1==1{ sub(/[[:space:]]*[0-9]+[[:space:]]*/,"",$0); print}' 

  • sort -k2 -n file - 按第二个字段对文件进行数字排序

  • uniq -f1 -c - 带有出现次数的输出行(-f1 - 跳过文件中的第一个字段)

  • awk '$1==1{ $1=""; print}' - 打印仅出现一次的行($1==1 - 检查来自uniq 命令的计数值)

【讨论】:

  • 我想知道为什么这也有相同的结果:sort -k2 f | uniq -f3 -c | awk '$1==1 {$1=""; print}'
  • @JohnGoofy,这个uniq -f3 -c 将跳过整个前 3 个字段,从第 4 个字段开始处理
  • @αԋɱҽԃαмєяιcαη,也许,他们有所不同。你可以选择性地发布那些重复的行吗?
  • @JohnGoofy 所有各种uniqs 都会产生相同的结果,因为在发布的示例输入中,字段 2 中相同的行在之后的所有其他字段中也相同,所以不管如何在此示例中您跳过许多字段以获得预期的输出。换句话说,这是一个测试给定解决方案是否有效的坏例子。
  • @EdMorton,我同意这一点:样本远非理想。我刚回家,上传了实际的 OP 文件 (102038),直到现在我才看到问题
【解决方案2】:

使用awk

#Input
awk '{R[i++]=$0;f=$1;$1="";N[$0]++;}
     END{for(i=0;i<NR;i++){
     temp=R[i];sub(/^[[:digit:]]*\, /,"",R[i]);
     if(N[" "R[i]]==1){print temp}}}' filename
#Output
435979, 335086, 803, 6, 19, ANNI BRENDA
436143, 335151, 545, 4, 23, Agrawal Abhishek
436723, 335387, 386, 2, 19, Bhati Naintara
438141, 325426, 145, 11, 19, Teh Joshua

【讨论】:

  • @αԋɱҽԃαмєяιcαη 你的问题一点都不清楚。我的回答给了你你需要的确切输出。你说it's keep duplicated是什么意思?
  • 您的意思是说如果该名称出现两次则不应打印该行?
【解决方案3】:

这就是你所需要的:

$ awk 'NR==FNR{c[$2]++;next} c[$2]==1' file file
435979, 335086, 803, 6, 19, ANNI BRENDA
436143, 335151, 545, 4, 23, Agrawal Abhishek
436723, 335387, 386, 2, 19, Bhati Naintara
438141, 325426, 145, 11, 19, Teh Joshua

【讨论】:

  • 是的,我很肯定,您可以在我的回答中看到,鉴于您提供的示例输入,它会产生您所要求的输出,所以不知道为什么您会说它没有做任何事情。等一下 - 在您的真实输入文件中,您是否有可能在每个逗号后没有空格,因此您的输入行看起来像 438141,325426,145,11,19,Teh Joshua 而不是 438141, 325426, 145, 11, 19, Teh Joshua 如您在问题中显示的那样?如果是这样,那么发布的答案都不适合您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 2022-01-23
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多