将几行从一个文件复制到另一个文件

将几行从一个文件复制到另一个文件

我想使用 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。相反,由于您知道蛋白质序列将始终以大写形式出现并以 结尾",因此您可以匹配:

  1. 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*$)。

  2. Perl

    perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat 
    

    这里的想法是相同的,...操作员指定一个范围并打印两个模式之间的线条。

  3. awk

    awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat 
    

    在这里,我们将变量设置a为 ,1如果该行与第一个模式匹配,则为 ,0如果它与最后一个模式匹配,awk则为 。然后,我们告诉打印。由于在第二个模式设置为之前调用了 ,因此这a也将包括包含第二个模式的行。1printa0

相关内容