我有以下输入
ASR cAND text1 (p .Pro221Leu)
GMPPB cAND text2 c .1069G> A(p.Val357Ile)
KLHL40 cAND text3
GMPPB cAND text4 c .220C> T(p.Arg74Ter)
我想在粗体之间打印任何文字,即 cAND 和((p 或 c )之间的文字
注意:text3不是预期的,因为它不能满足上述条件。
expected output(underlined)
text1
text2
text4
regex used
grep "cAND.+(c\.|\(p)"
但是我没有得到预期的输出。请告诉我我的正则表达式有什么问题?谢谢
答案 0 :(得分:4)
在Perl模式下使用grep,您可以执行此操作(请参阅demo):
grep -P "cAND[ ]*\K\S+(?=[ ]*(?:c.|\(p))" some_path_or_files
它是如何运作的?贪婪。强>
cAND[ ]*
确保我们拥有cAND
并且还匹配以下空格\K
会丢弃到目前为止我们匹配的内容,以便我们可以返回干净的字符串,例如text1
\S+
匹配我们想要的字符:任何非空格字符(?=[ ]*(?:c.|\(p))
前瞻确保后面的内容是空格和c或p分隔符出了什么问题?
.+
中的cAND.+(c\.|\(p)
是“贪婪的”:它会占用所有字符,直到字符串结束,然后它会回溯直到(c\.|\(p)
可以满足。因此,它会占用最后一个c或p的字符,例如:cAND text2 c.1069G>A (p
text1
。带有Lookarounds的备用正则表达式
因为你正在研究正则表达式......这也有效。
(?<=cAND).*?(?=c.|\(p)
<强>参考强>
答案 1 :(得分:1)
使用sed -r
:
sed -r 's/^.*cAND ([^ ]+)( \(?[cp].*)?$/\1/' file
text1
text2
text3
text4
PS:在OSX上使用sed -E
。
答案 2 :(得分:0)
那个通过awk,
$ awk '$2=="cAND" && $4~/^c|^\(p/ { print $3}' file
text1
text2
text4
检查第2列为cAND
,第4列是以c
还是(p
开头。如果满足两个条件,则将打印该对应行的第3列。