列中的重复项:随机保留一个

时间:2018-03-16 14:42:52

标签: bash awk duplicates multiple-columns

我有一个文件(input.txt),其结构与此类似:

 abc    1
 bcd    a
 cde    1
 def    4
 efg    a
 fgh    3

我想删除第2列中的重复项,以便在该列中只包含唯一的字符串(独立于第1列中的字符串)。但是所选择的行应该选择随意。输出可以例如

 bcd    a
 cde    1
 def    4
 fgh    3

我尝试创建一个列出重复项的文件(使用awk '{print $2}' input.txt | sort | uniq -D | uniq),但之后我只设法用awk '!A[$2]++'删除它们,而不是随机保留其中一个重复项。

3 个答案:

答案 0 :(得分:5)

预处理输入以使其随机化:

shuf input.txt | awk '!A[$2]++'

答案 1 :(得分:1)

使用GNU awk实现真正的多维数组:

$ awk '{a[$2][++cnt[$2]]=$0} END{srand(); for (k in a) print a[k][int(rand()*cnt[k])+1]}' file
 efg    a
 cde    1
 fgh    3
 def    4

其他问题:

$ awk '{keys[$2]; a[$2,++cnt[$2]]=$0} END{srand(); for (k in keys) print a[k,int(rand()*cnt[k])+1]}' file
 bcd    a
 abc    1
 fgh    3
 def    4

答案 2 :(得分:1)

使用perl

$ perl -MList::Util=shuffle -e 'print grep { !$seen{(split)[1]}++ } shuffle <>' input.txt
 def    4
 fgh    3
 bcd    a
 abc    1
  • -MList::Util=shuffleshuffle模块
  • 获取List::Util功能
  • shuffle <>此处<>会将所有输入行作为数组,然后进行随机播放
  • grep { !$seen{(split)[1]}++ }基于空格作为分隔符,基于每个数组元素的第2个字段过滤行


使用ruby

$ ruby -e 'puts readlines.shuffle.uniq {|s| s.split[1]}' input.txt
 abc    1
 bcd    a
 fgh    3
 def    4
  • readlines将输入文件中的所有行作为数组
  • shuffle随机化元素
  • uniq获取独特元素
    • {|s| s.split[1]}基于第二个字段值,使用空格作为分隔符
  • puts打印数组元素