【问题标题】:Adding "#" in front of the first 8 lines matching STRING在匹配 STRING 的前 8 行前添加“#”
【发布时间】:2015-07-07 17:27:12
【问题描述】:

这个问题有点混乱,所以我只举一个例子。

假设我有以下情况:

$ grep -P "locus_tag\tM715_1000193188" Genome.tbl -B1 -A8
193188  193066  gene
            locus_tag   M715_1000193188
193188  193066  mRNA
            product hypothetical protein
            protein_id  gnl|CorradiLab|M715_1000193188
            transcript_id   gnl|CorradiLab|M715_mrna1000193188
193188  193066  CDS
        product hypothetical protein
        protein_id  gnl|CorradiLab|M715_1000193188
        transcript_id   gnl|CorradiLab|M715_mrna1000193188

我想在“locus_tag M715_1000193188”后面的8行加上“#”,这样我修改后的文件就变成了这样:

193188  193066  gene
            locus_tag   M715_1000193188
#193188 193066  mRNA
#           product hypothetical protein
#           protein_id  gnl|CorradiLab|M715_1000193188
#           transcript_id   gnl|CorradiLab|M715_mrna1000193188
#193188 193066  CDS
#       product hypothetical protein
#       protein_id  gnl|CorradiLab|M715_1000193188
#       transcript_id   gnl|CorradiLab|M715_mrna1000193188

基本上我有一个包含大约 3000 个不同基因座标签的文件,其中 300 个我需要注释掉 mRNA 和 CDS 特征,因此 locus_tag 行之后的 8 行。

有什么方法可以用 sed 做到这一点?文件中还有其他类型的信息需要保持不变。

谢谢, 阿德里安

【问题讨论】:

    标签: awk sed text-parsing


    【解决方案1】:

    如果你可以使用awk,应该这样做:

    awk 'f&&f-- {$0="#"$0} /locus_tag/ {f=8} 1' file
    193188  193066  gene
                locus_tag   M715_1000193188
    #193188  193066  mRNA
    #            product hypothetical protein
    #            protein_id  gnl|CorradiLab|M715_1000193188
    #            transcript_id   gnl|CorradiLab|M715_mrna1000193188
    #193188  193066  CDS
    #        product hypothetical protein
    #        protein_id  gnl|CorradiLab|M715_1000193188
    #        transcript_id   gnl|CorradiLab|M715_mrna1000193188
    

    【讨论】:

    • 很好,它有效!如何直接在文件中进行更改?我需要这样做 300 次,所以每次我进行编辑时是否可以直接更改“文件”?假设我有一个 for 循环,其中 $i 是轨迹名称,awk 看起来像这样 awk 'f&&f-- {$0="#"$0} /locus_tag\t$i/ {f=8} 1' 文件
    • 要使awk 更新原始文件,请执行:awk 'commands' file >tmp && mv tmp file。如果你有gawk >= `4.1`,你可以使用gawk -i
    • 或通过 awk 传递所有轨迹值,并在输入文件中一次性完成所有更改。
    • 我遇到了一些麻烦。某些基因座编号(例如 M715_80001)存在问题,因为与其他基因座编号(例如 M715_8000123 M715_80001654)部分匹配。我怎样才能调整它以获得完全匹配?我尝试添加一个 \n 字符,但它不起作用 awk 'f&&f-- {$0="#"$0} /locus_tag\tM715_80001\n/ {f=8} 1'
    • 你可以这样做:awk 'f&&f-- {$0="#"$0} $1=="locus_tag" && $2=="M715_80001" {f=8} 1' file
    【解决方案2】:

    sed 支持范围Addresses,可以在这里做你想做的事情。

    sed -e '/locus_tag\tM715_1000193188/,+8s/^/#/' file
    

    如 cmets 中所述,此范围地址格式是 GNU sed 特定的。

    【讨论】:

    • 我喜欢。除此之外:sed 直接理解\t/pattern/,+8 形式的范围是 GNU 特定的;记下这一点可能是谨慎的。
    • 此解决方案计算字符串后面的 8 行以及找到该字符串的行。是否可以不注释找到字符串的行?谢谢
    • 嗯...好问题。我不确定 sed 是否可以轻松做到这一点。 vim 虽然支持这种范围。我认为你需要一个标签和一个替换测试或类似的东西来 sed。
    • 除了比赛前的 2 行之外,有没有办法做到这一点?我尝试了 -2s 而不是 +8s,但没有奏效。
    • sed 绝对不能那样倒退。我也不知道 sed 在范围上做“数学”。 vim 可以做这两件事,但不适合大文件。您可以使用 awk 通过手动保持行的滑动窗口来做到这一点,但我不知道有什么可以以流方式执行此操作(可能是 perl,但我不知道)。
    【解决方案3】:
    $ cat tst.awk
    BEGIN { split(tags,tmp); for (i in tmp) tagsA[tmp[i]] }
    c&&c-- { $0 = "#" $0 }
    ($(NF-1) == "locus_tag") && ($NF in tagsA) { c=8 }
    { print }
    
    $ awk -v tags="M715_1000193188 M715_1000193189 M715_1000193190" -f tst.awk file
    193188  193066  gene
                locus_tag   M715_1000193188
    #193188  193066  mRNA
    #            product hypothetical protein
    #            protein_id  gnl|CorradiLab|M715_1000193188
    #            transcript_id   gnl|CorradiLab|M715_mrna1000193188
    #193188  193066  CDS
    #        product hypothetical protein
    #        protein_id  gnl|CorradiLab|M715_1000193188
    #        transcript_id   gnl|CorradiLab|M715_mrna1000193188
    

    只需列出您关心的所有 300 个基因座标记值,如上所示的 3 个示例。

    【讨论】:

      【解决方案4】:

      这可能对你有用(GNU sed):

      sed 's/.*/\\#locus_tag\\s*&#,+9{\\#locus_tag\\s*&#n;s|^|#|}/' tag_file |
      sed -i -f - file
      

      这会从标记文件创建一个 sed 脚本,并将# 添加到标记匹配后的八行中。

      【讨论】:

        猜你喜欢
        • 2016-03-15
        • 2012-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多