grep:结合否定匹配和After(搜索不包含单词片段的蛋白质序列)

grep: combine negative match with After (search for protein sequences that do not contain the word fragment)

我有一个 fasta 序列,我想过滤掉所有在 header 中包含单词 Fragment 的序列。

我想我可以使用 grep-A 1 (因为蛋白质序列总是在一行上)和 -i (以防片段没有写成大写)并使用它使用 -v,但以某种方式反转结果无法按预期工作。

>tr|A0A534K2W8|A0A534K2W8_9EURY Epoxide hydrolase 1 (Fragment) OS=Euryarchaeota archaeon OX=2026739 GN=E6K10_05355 PE=4 SV=1 
MSNTPDFNRR...
>tr|A0A4S3JUN3|A0A4S3JUN3_9EURO AB hydrolase-1 domain-containing protein OS=Aspergillus tanneri OX=1220188 GN=ATNIH1004_010243 PE=4 SV=1
MRDKYTPATL...
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...
>tr|A0A2G8L4U1|A0A2G8L4U1_STIJA Putative epoxide hydrolase 1-like OS=Stichopus japonicus OX=307972 GN=BSL78_07808 PE=4 SV=1
MVHGWPGSFY...

如果我想保留 Fragment 的序列,它工作正常

grep -i "fragment" -A 1 test.fasta                                             
>tr|A0A534K2W8|A0A534K2W8_9EURY Epoxide hydrolase 1 (Fragment) OS=Euryarchaeota archaeon OX=2026739 GN=E6K10_05355 PE=4 SV=1 
MSNTPDFNRR...
--
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...

但如果我想反转匹配,这就是结果。

grep -i "fragment" -A 1 -v test.fasta
MSNTPDFNRR...
>tr|A0A4S3JUN3|A0A4S3JUN3_9EURO AB hydrolase-1 domain-containing protein OS=Aspergillus tanneri OX=1220188 GN=ATNIH1004_010243 PE=4 SV=1
MRDKYTPATL...
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...
>tr|A0A2G8L4U1|A0A2G8L4U1_STIJA Putative epoxide hydrolase 1-like OS=Stichopus japonicus OX=307972 GN=BSL78_07808 PE=4 SV=1
MVHGWPGSFY...

我哪里出错了?

问题是 -v 不能与上下文切换一起使用。如果你有 GNU grepPCRE,那么你可以使用复杂的正则表达式:

grep --no-group-separator -xiP -A 1 '>((?!fragment).)+'

注意使用 --no-group-separator 以避免不同匹配之间出现 ---P 启用 PCRE-x 确保整行匹配。 >((?!fragment).)+ 确保 fragment 不出现在以 > 开头的行中(有关更多说明,请参阅 Variable-length lookbehind-assertion alternatives for regular expressions


但是,对于这种情况,您最好使用 awk

# with GNU awk
awk -v IGNORECASE=1 '/^>/ && !/fragment/{f=2} f && f--'
# any awk
awk '/^>/ && tolower([=11=]) !~ /fragment/{f=2} f && f--'

此处,f=2 1 大于匹配后所需的行数。 /^>/ && !/fragment/ 将只匹配以 > 开头且不包含 fragment

的行

另请参阅 lines around matching regexp 了解更多此类示例。