【问题标题】:grep -f return only first match (of many)grep -f 只返回第一个匹配(许多)
【发布时间】:2012-07-02 11:06:32
【问题描述】:

尝试从命令行中获得更多信息:

我有一个文件:

CHR25   1192279 Y       Exonic  NA      exon    2       [1/1]   1192145 1192322
CHR25   1192279 Y       Exonic  NA      CDS     2       [1/1]   1192145 1192322  
CHR25   1739394 Y       Exonic  NA      CDS     2       [1/2]   1739294 1739456

我想根据第 2 列获得唯一行。我已经完成了

cat file | cut -f 2 | uniq > grepfile

但我不确定现在如何使用 grep -f 每行获得一个匹配项,就像我之前所做的那样。使用 -m1 or | head -n 1 只会给出第一个匹配行。我希望第一行匹配 'grepfile' 中的每一行。

期待答案=)

【问题讨论】:

  • 所以您只需要示例中的第一行和第三行?还是第二和第三?哪个重要?
  • 从问题中不清楚您想要实现什么。根据您已经提供的示例输入文件添加您想要获得的最终输出,我相信我们将能够提供帮助。
  • 我想我明白了。这是 awk 的工作。 awk '!s[$2]++'
  • 我只想得到grepfile中每一行的第一个匹配项
  • @AlanCurry 很好用,真的需要了解一下 awk

标签: unix command-line grep


【解决方案1】:

这个 awk 命令的工作原理是构建一个由已经看到的第二个字段值组成的关联数组。

awk '!s[$2]++'

关联数组称为s。该表达式查找 $2(输入行的第二列)并应用一个后增量,它将在第一次调用时返回 0,此后返回非零。然后我反转它,第一次看到每 2 美元时产生 1,之后每次都产生 0。如果选择表达式为真,则 awk 的默认操作是打印。

当行数大到足以再次回绕到 0 时,请注意。

【讨论】:

  • +1 for awk .. 应该注意的是,如果您使用 csh/tcsh,则需要转义 !,因此 awk '\!s[$2]++' 将起作用。
  • +1 很好的解决方案,但是要多花几个字符来使解释变得多余并避免溢出呢? awk 's[$2]==0 { s[$2]=1; print }'
【解决方案2】:

这也可以:

sort -u  -k2,2 file

给予:

CHR25   1192279 Y       Exonic  NA      exon    2       [1/1]   1192145 1192322
CHR25   1739394 Y       Exonic  NA      CDS     2       [1/2]   1739294 1739456

-u 调用 uniq-k2,2 表示对字段 2(且仅字段 2)进行排序,如在排序 man page 上所见。

【讨论】:

  • -u 和 --unique 表示唯一,如 uniq。但是没有调用 uniq 命令。
  • @richard 对,你是 .. 感谢您指出这一点。我应该更仔细地看一下手册页,我才看到 uniq* :)
  • @user1495853 不客气。如果此页面上的任何这些解决方案有帮助,请随时为它们投票。并考虑在答案旁边选择您最喜欢的和accept it by clicking on the checkmark。这将奖励双方一些代表点并将此问题标记为已解决。
【解决方案3】:

如果 Perl 没问题,你可以这样做:

perl -nale '$h{$F[1]}=$_ if(!$h{$F[1]});END{print $h{$_}for(keys(%h));}' file

【讨论】:

  • 我可以在 Perl 中完成(还有更多行),但我正在尝试使用命令行。不过还是谢谢。
  • 我可以在 perl 中做到这一点,几乎和在 awk 中一样:perl -nae 'print if !$s{$F[1]}++'
【解决方案4】:

因为 uniq 只查看相邻的行,而 sort 改变了顺序。您需要更多代码。

cat -n input-file | sort --key=3,3 --unique | sort | cut -f2- >output-file
  1. cat -n 添加序列号。
  2. sort --key=3,3 --unique 删除字段 2 上的重复项。注意:由于 cat -n,密钥编号高一。
  3. sort 按原顺序放回原位。
  4. cut -f2- 获取序列号。

【讨论】:

    猜你喜欢
    • 2012-09-30
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多