首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用grep进行模式匹配时保持行结构

使用grep进行模式匹配时保持行结构
EN

Stack Overflow用户
提问于 2013-02-21 18:06:16
回答 2查看 714关注 0票数 1

我有一个关于grep的问题。我正在寻找多行文本中的特定模式。通常在同一行上有多个匹配项。我已经知道了如何提取模式,但是grep会将每个匹配项放在新的一行上。有什么方法可以阻止grep这样做吗?理想情况下,我希望提取所有匹配项并保留原始文件的行结构。

下面是一个示例:

一个输入行(其中有数千行):

代码语言:javascript
运行
复制
MUC3A|ENST00000414964[in] MUC3A|ENST00000422757[in] MUC3A|ENST00000319509[in] MUC3A|ENST00000483133[in] RP11-395B7.2.1|ENST00000420080[me] RP11-395B7.2.1|ENST00000438198[me] RP11-395B7.2.1|ENST00000434775[5g] MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g] MUC3A|ENST00000480291[5g] 

我的grep命令:

代码语言:javascript
运行
复制
grep -oe MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]

我当前的输出:

代码语言:javascript
运行
复制
MUC12|ENST00000536621[5g]
MUC12|ENST00000379442[5g]

我的理想输出是:

代码语言:javascript
运行
复制
MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

有什么想法吗?如果任何人能提供任何见解,我将非常感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-21 21:07:12

代码语言:javascript
运行
复制
$ awk '{
   s=""
   for (i=1;i<=NF;i++) {
      if ($i ~ /MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]/) {
         printf "%s%s",s,$i
         s=" "
      }
   }
   print ""
}' file
MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

我会稍微修改一下你的RE来锚定表达式,为了简洁和可移植性使用字符类而不是显式的范围,并且寻找1个或更多的字符(+)而不是允许零(*):

代码语言:javascript
运行
复制
$ awk '{
   s=""
   for (i=1;i<=NF;i++) {
      if ($i ~ /^MUC12\|[[:alnum:]-]+\[[[:alnum:]]+\]$/) {
         printf "%s%s",s,$i
         s=" "
      }
   }
   print ""
}' file
MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

我还将"|“移出了字符列表,因为它似乎不属于您发布的示例输入。

票数 1
EN

Stack Overflow用户

发布于 2013-02-21 23:55:03

当您设置-o标志时,grep将在新行上分别打印每个匹配项,并且无法更改此行为。简单的解决方法是让grep打印出每个匹配的行号,然后连接连续编号的行号。您可以使用awk来完成此操作。像这样运行:

代码语言:javascript
运行
复制
< file grep -one "MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]" | awk -f script.awk

script.awk的内容

代码语言:javascript
运行
复制
BEGIN {
    FS=":"
}

$1 == y {
    sub(/[^:]+:/,"")
    r = (r ? r OFS : "") $0
    next
}

x {
    print x, r
    r=""
}

{
    x=$0
    y=$1
    sub(/[^:]+:/,"",x)
}

END {
    print x, r
}

或者,下面是一行代码:

代码语言:javascript
运行
复制
< file grep -one "MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]" | awk -F ":" '$1 == y { sub(/[^:]+:/,""); r = (r ? r OFS : "") $0; next } x { print x, r; r="" } { x=$0; y=$1; sub(/[^:]+:/,"",x) } END { print x, r }'

这里介绍的方法可以应用于grep支持的任何正则表达式。与公认的答案不同,对于非空格分隔的正则表达式,这种方法不会失败-这可能非常重要。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14999440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档