【问题标题】:awk + How do I find duplicates in a column?awk + ​​如何在列中查找重复项?
【发布时间】:2020-10-13 22:44:15
【问题描述】:

如何在列中查找重复项?

$ head countries_lat_long_int_code3.csv | cat -n
     1  country,latitude,longitude,name,code
     2  AD,42.546245,1.601554,Andorra,376
     3  AE,23.424076,53.847818,United Arab Emirates,971
     4  AF,33.93911,67.709953,Afghanistan,93
     5  AG,17.060816,-61.796428,Antigua and Barbuda,1
     6  AI,18.220554,-63.068615,Anguilla,1
     7  AL,41.153332,20.168331,Albania,355
     8  AM,40.069099,45.038189,Armenia,374
     9  AN,12.226079,-69.060087,Netherlands Antilles,599
    10  AO,-11.202692,17.873887,Angola,244

例如,这在第 5 列中有重复项。

     5  AG,17.060816,-61.796428,Antigua and Barbuda,1
     6  AI,18.220554,-63.068615,Anguilla,1

如何查看此文件中的所有其他内容?

我知道我能做到:

awk -F, 'NR>1{print $5}' countries_lat_long_int_code3.csv | sort

而且我可以目测看看是否有重复,但有没有更好的方法?

或者我可以这样做: 找出完全有可能的情况

$ awk -F, 'NR>1{print $5}' countries_lat_long_int_code3.csv | sort | wc -l
210

找出有多少唯一值

$ awk -F, 'NR>1{print $5}' countries_lat_long_int_code3.csv | sort | uniq | wc -l
183

因此最多有 27 (210-183) 个重复。

EDIT1

我想要的输出如下所示,基本上是所有列,但只显示重复的行:

 5  AG,17.060816,-61.796428,Antigua and Barbuda,1
 6  AI,18.220554,-63.068615,Anguilla,1

【问题讨论】:

  • awk -F, 'NR>1{print $5}' countries_lat_long_int_code3.csv | sort | uniq -c | grep -v '^ *1 *' 呢? Taht 将使用 uniq -c 对所有重复的行进行分组,并删除所有出现一次的行。
  • 你想要的输出是什么。重复代码、重复记录、唯一代码的计数?
  • 你只关心第 5 个字段还是其他字段?

标签: awk


【解决方案1】:

这会给你重复的代码

awk -F, 'a[$5]++{print $5}'

如果您只对重复代码的计数感兴趣

awk -F, 'a[$5]++{count++} END{print count}'

要打印重复的行试试这个

awk -F, '$5 in a{print a[$5]; print} {a[$5]=$0}'

这将打印在 col $5 中找到重复项的整行:

awk -F, 'a[$5]++{print $0}'

【讨论】:

  • 只有一次重复时,您的最后一个工作正常。但是,如果有另一行带有 $5 == 1,那么它会再次打印 Anguilla 行。你可以很容易地解决这个问题。我使用了一个稍微冗长的:awk -F, '{if (count[$5] > 1) print $0; else if (count[$5] == 1) { print save[$5]; print $0; } else save[$5] = $0; count[$5]++; }'。 count 数组记录了之前看到 $5 的次数。如果不止一次,只打印新记录;如果只有一次,则打印保存的(第一条)记录和新记录;否则,这是新的,所以节省 0 美元。无论如何增加计数。
  • aa[$5] 中代表什么?
  • 它是保存$5作为键的数组的名称,该值每次都会递增,因此总体而言,它的行为类似于此上下文中的python Counter 对象。
  • 当我尝试运行它时,它只是卡住了(我的文件包含 400 万行 ~500 Mb)
  • 它不应该卡住,它应该从第一个重复记录开始打印。您的文件大小对于脚本开始打印应该无关紧要。也许你正在做其他事情?
【解决方案2】:

这是我可以猜到的内存攻击性较小的:

$ cat infile
country,latitude,longitude,name,code
AD,42.546245,1.601554,Andorra,376
AE,23.424076,53.847818,United Arab Emirates,971
AF,33.93911,67.709953,Afghanistan,93
AG,17.060816,-61.796428,Antigua and Barbuda,1
AI,18.220554,-63.068615,Anguilla,1
AL,41.153332,20.168331,Albania,355
AM,40.069099,45.038189,Armenia,374
AN,12.226079,-69.060087,Netherlands Antilles,599
AO,-11.202692,17.873887,Angola,355

$ awk -F\, '$NF in a{if (a[$NF]!=0){print a[$NF];a[$NF]=0}print;next}{a[$NF]=$0}' infile
AG,17.060816,-61.796428,Antigua and Barbuda,1
AI,18.220554,-63.068615,Anguilla,1
AL,41.153332,20.168331,Albania,355
AO,-11.202692,17.873887,Angola,355

注意:出于测试目的,我已包含另一个副本。

【讨论】:

    【解决方案3】:

    如果您只想打印出在同一个文件中重复的唯一值,只需在 awk 末尾添加:

    awk ... ... |排序 | uniq -u

    这将仅按字母顺序打印唯一值

    【讨论】:

    • 这不是问题,问题已经有了这个解决方案
    猜你喜欢
    • 2014-09-03
    • 1970-01-01
    • 2013-03-29
    • 2013-02-21
    • 2018-11-07
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多