我想使用 grep 将行与行之间/protein_id=
直到显示的蛋白质序列结束的所有行从一个文件复制到另一个文件。例如,从此输入:
CDS 448..1269
/gene="nptII"
/note="neomycin phosphotransferase II"
/codon_start=1
/product="kanamycin resistance protein"
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
regulatory 1443..2148
我想要这个输出:
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
请注意,输入可能会有所不同,因为以 开头的行regulatory
可能会被替换为其他内容。不变的是,序列以大写字母给出,并以 结尾"
。使用 grep 可以实现吗?
答案1
pcregrep
是一个使用与 perl 5 兼容的正则表达式的 grep 实用程序。Perl 风格的正则表达式具有许多标准 POSIX 正则表达式所没有的有用功能。这基本上与 grep 相同,但正则表达式语法不同。
sudo apt-get install pcregrep
pcregrep -M .*'/protein_id=.*(\n|.)*\"' path/to/input-file
/protein_id
是开始搜索词,"
是结束搜索词。
以下是对起始搜索词和终止搜索词之间的所有行进行多行搜索的命令的通用示例:
pcregrep -M .*'START-SEARCH-TERM.*(\n|.)*END-SEARCH-TERM' path/to/SOURCE-FILE >> path/to/DESTINATION-FILE
在哪里:
- SOURCE-FILE 是包含数据的文件
- DESTINATION-FILE 是将复制结果的文件
- START-SEARCH-TERM 是起始搜索词
- END-SEARCH-TERM 是结束搜索词
-M, --multiline
允许模式匹配多行。
答案2
不,grep
无法跨多行匹配。您可以pcregrep
按照@karel 所示使用 来执行此操作,但不能使用纯grep
。相反,由于您知道蛋白质序列将始终以大写形式出现并以 结尾"
,因此您可以匹配:
sed
sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
该
sed
模式/foo/,/bar/{p}
表示“打印foo
和之间的所有行bar
。-n
抑制正常输出,因此仅打印请求的行。请注意,/
需要/protein_id=
转义(\/
),因为/
是匹配运算符的一部分。第二个模式稍微复杂一些,它在行首查找 0 个或更多空格(^\s*
),然后查找一个或多个大写字母,后跟双引号([[:upper:]]"
),然后查找 0 个或更多空格字符,直到行尾(\s*$
)。Perl
perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat
这里的想法是相同的,
...
操作员指定一个范围并打印两个模式之间的线条。awk
awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat
在这里,我们将变量设置
a
为 ,1
如果该行与第一个模式匹配,则为 ,0
如果它与最后一个模式匹配,awk
则为 。然后,我们告诉打印。由于在第二个模式设置为之前调用了 ,因此这a
也将包括包含第二个模式的行。1
print
a
0