微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

打印整行,当发现重复时

如何解决打印整行,当发现重复时

这是我输入的片段:

DGD3 SOL10
DGD53 SOL15
DGD100 SOL15
DGD92 SOL20
DGD41 SOL22
DGD62 SOL35
DGD13 SOL40
DGD13 SOL40

我的预期输出

DGD53 SOL15
DGD100 SOL15
DGD13 SOL40
DGD13 SOL40

在我的数据中,我有时会重复 SOL(不超过两次重复,而不是例如文件中某些 SOL 的三倍,但仅重复)。 SOL 在我的第二列中($2)。因此,当我找到重复的 SOL($2)时,我需要一个打印整行(DGD 和 SOL)的程序。你能帮我吗?

解决方法

以 awkish 风格添加另一种方式,在第一次读取 Input_file 时获取所有值计数并在第二次读取时根据它们的计数打印所有值。公平警告,这可能不如其他 2 个解决方案快,但从理解目的来看应该很简单。

awk '
FNR==NR{
  count[$2]++
  next
}
(count[$2]>1)
' Input_file  Input_file
,

使用您的示例(按第二个字段排序),您可以执行以下操作:

$ awk 'l2==$2{print ll; print; next}
       {ll=$0; l2=$2}' file

打印:

DGD53 SOL15
DGD100 SOL15
DGD13 SOL40
DGD13 SOL40

这类似于 Unix uniq 过滤器,它只打印相邻的重复项。

如果文件中的重复项是随机的,您可以先排序:

$ awk 'l2==$2{print ll; print; next}
            {ll=$0; l2=$2}' <(sort -k 2 file) 

或者,对文件进行两次传递:

$ awk 'FNR==NR{cnt[$2]++; next} cnt[$2]>1' file file

或者,仅识别 2 个或更多的 SOL 标签,您可以:

$ awk '++cnt[$2]==2' file   

您可以使用相同的方法生成 grepsed 的命令代码,以从未排序的文件中打印:

$ sed -n -f <(awk '++cnt[$2]==2 {printf "/[[:space:]]%s$/p\n",$2}' file) file

所以选择是:

  1. 使用更多内存(通过将整个文件缓存在以 $2 值键控的内存中),或
  2. 先排序,或者
  3. 遍历文件两次。
,

您可以使用此 awk,它将打印重复不一定是相邻的

awk '$2 in map {print map[$2] ORS $0} {map[$2] = $0}' file

DGD53 SOL15
DGD100 SOL15
DGD13 SOL40
DGD13 SOL40
,

如果您的文件在第二个字段中排序,uniq 是为该任务设计的,具有正确的选项。

$ uniq -f1 -D file

DGD53 SOL15
DGD100 SOL15
DGD13 SOL40
DGD13 SOL40

跳过第一个字段,打印所有重复项...

,

另一个 awk。单次运行,不需要对文件进行排序,如果第二个字段的实例超过 2 个,则可以正常工作。在最坏的情况下,它会散列内存中的完整文件并且不产生任何输出:

$ awk '{
    if(!c[$2]++)           # if first instance of $2
        a[$2]=$0           # store it
    else {
        if(c[$2]==2) {     # if second instance 
            print a[$2]    # print previous
            delete a[$2]   # no need to waste my memory any more
        } 
        print              # after first instance of $2 we always print current
    }
}' file

输出:

DGD53 SOL15
DGD100 SOL15
DGD13 SOL40
DGD13 SOL40

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。