【问题标题】:How can i remove a line only if it is followed by a line that starts with the same character?仅当一行后跟以相同字符开头的行时,如何才能删除该行?
【发布时间】:2017-08-02 18:54:27
【问题描述】:

我需要一些关于 sed 或 awks 的帮助。

我如何才能删除一行,如果它后面跟着一个以相同字符开头的行(在这种情况下是>)?

例如我有这个:

>1_SRR1422294
ATCGTCAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAT
>2_SRR1422294
CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
>5_SRR1422298
>5_SRR1422294
CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
>6_SRR1422294
>6_SRR1422250
TGTTCATGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC
>9_SRR1422294
GCGACTAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC

我想得到这个:

>1_SRR1422294
ATCGTCAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAT
>2_SRR1422294
CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
>5_SRR1422294
CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
>6_SRR1422250
TGTTCATGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC
>9_SRR1422294
GCGACTAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC

请注意,并非所有行都有相同的数字,但它们都有相同的格式,这就是我想使用正则表达式的原因。如果您能解释如何阅读您生成的代码,那就太好了。

非常感谢!

【问题讨论】:

  • 使用 GNU grep:grep -Poz '^>.*\n[^>].*' file

标签: regex awk sed fasta reformat


【解决方案1】:

如果整个文件遵循该模式(以> 开头的一些行,您只需要最后一行,然后是应始终打印的单行),您可以使用如下内容:

awk '/^>/ { latest=$0 } !/^>/ { if (latest) { print latest; latest="" } print }'

如果该行以> 开头,则它会被记住(存储在变量latest 中)但不会打印。如果该行不以> 开头,则打印它,但仅在第一次打印最近存储在latest 中的任何内容之后。

条件意味着每个打印的> 行只会出现一次,即使一行中有多个非> 行。由于您的示例数据中不会发生这种情况,因此您可能不需要复杂性,并且可以使用这个更简单的无条件版本:

awk '/^>/ { latest=$0 } !/^>/ { print latest; print }'

【讨论】:

    【解决方案2】:

    只需使用带有-w(--check-chars=N) 选项的uniq 命令即可轻松实现所需的结果:

    cat testfile | uniq -w 3
    

    输出:

    >1_SRR1422294
    ATCGTCAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAT
    >2_SRR1422294
    CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
    >5_SRR1422298
    CGTCAGACGTAGGGTTGCGCTCGTTGCGGGACTTAACCCAACATCTCACGACACGAGCTGACGACAGCCATGCAG
    >6_SRR1422294
    TGTTCATGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC
    >9_SRR1422294
    GCGACTAGGTAGGGTTGCGCTCGTTGCGGGACTTAACCCACATCTCACGACACGAGCTGACGACAGCCATGCAGC
    

    -w, --check-chars=N
    在行中比较不超过 N 个字符

    http://man7.org/linux/man-pages/man1/uniq.1.html


    它会比较每行的前N个字符来判断是否有重复的行

    【讨论】:

      【解决方案3】:

      尝试:如果您的数据与给定的示例 Input_file 相同,那么以下内容可能对您有所帮助。

      awk '/^>/{A=$0;next} {print A ORS $0;A=""}'  Input_file
      

      【讨论】:

        【解决方案4】:

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

        sed 'N;/^>.*\n>/!P;D' file
        

        将两行读入模式空间,如果第一行和第二行以> 开头,则不打印其中的第一行。

        【讨论】:

          【解决方案5】:
          sed 'N;/^>.*\n\w/!D' file #(GNU sed)
          

          N:将下一行读入模式空间。
          /^>.*\n\w/!D:如果第一行以“>”开头且第二行不以字母开头,则删除第一行

          【讨论】:

            猜你喜欢
            • 2015-10-23
            • 1970-01-01
            • 2016-09-01
            • 2022-08-17
            • 1970-01-01
            • 2017-04-15
            • 1970-01-01
            • 2013-08-21
            • 1970-01-01
            相关资源
            最近更新 更多