【问题标题】:Filter (or 'cut') out column that begins with 'OS=abc'过滤(或“剪切”)以“OS=abc”开头的列
【发布时间】:2020-08-03 06:06:51
【问题描述】:

我的 .fasta 文件包含这种重复模式。

>sp|P20855|HBB_CTEGU Hemoglobin subunit beta OS=Ctenodactylus gundi OX=10166 GN=HBB PE=1 SV=1
asdfaasdfaasdfasdfa
>sp|Q00812|TRHBN_NOSCO Group 1 truncated hemoglobin GlbN OS=Nostoc commune OX=1178 GN=glbN PE=3 SV=1
asdfadfasdfaasdfasdfasdfasd
>sp|P02197|MYG_CHICK Myoglobin OS=Gallus gallus OX=9031 GN=MB PE=1 SV=4
aafdsdfasdfasdfa

我只想过滤掉包含 '>' 的行 THEN 过滤掉 'OS=' 之后和 'OX=' 之前的字符串,(例如 line1=Ctenodactylus gundi)

第一部分('>')很简单:

grep '>' my.fasta | cut -d " " -f 3 >> species.txt

问题是在'OS='之前字段的数量不是恒定的。

但 'OS=' 和 'OX=' 之间的列/字段数为 2。

【问题讨论】:

  • filter out 这个词非常含糊 - 它可能意味着 output only thisoutput everything except this
  • @ed-morton 很高兴知道

标签: regex awk sed grep cut


【解决方案1】:

您可以使用-P 选项启用基于PCRE 的正则表达式匹配,并使用环视模式确保匹配包含在OS=OX= 之间:

grep '>' my.fasta | grep -oP '(?<=OS=).*(?=OX=)'

请注意,-P 选项仅适用于 GNU 版本的 grep,默认情况下在某些环境中可能不可用。

【讨论】:

  • 我真的很喜欢这句话的简洁性。
【解决方案2】:

恕我直言awk 在这里会更可行(因为它可以同时处理正则表达式和条件部分的打印),请您尝试以下操作。

awk '/^>/ && match($0,/OS=.*OX=/){print substr($0,RSTART+3,RLENGTH-6)}' Input_file

输出如下。

Ctenodactylus gundi
Nostoc commune
Gallus gallus

说明:为上述代码添加详细说明。

awk '                                    ##Starting awk program from here.
/^>/ && match($0,/OS=.*OX=/){            ##Checking condition if line starts from > AND matches regex OS=,*OX= means match from OS= till OX= in each line, if both conditions are TRUE.
  print substr($0,RSTART+3,RLENGTH-6)    ##Then print sub string of current line, whose starting point is RSTART+3 to till RLENGTH-6 of current line.
}
' Input_file                             ##Mentioning Input_file name here.

【讨论】:

    【解决方案3】:

    在每个 UNIX 机器上的任何 shell 中使用任何 awk:

    $ awk -F' O[SX]=' '/^>/{print $2}' file
    Ctenodactylus gundi
    Nostoc commune
    Gallus gallus
    

    【讨论】:

    • 效果很好,我也喜欢这个简单的。谢谢你教我这个。
    【解决方案4】:

    sed解决方案:

    $ sed -nE '/>/ s/^.*OS=(.*) OX=.*$/\1/p' .fasta
    Ctenodactylus gundi
    Nostoc commune
    Gallus gallus
    

    -n 除非请求,否则不会打印模式空间; -E(扩展正则表达式)以便我们可以使用子表达式和反向引用。 s 命令的 p 标志表示“打印模式空间”。

    正则表达式应该匹配整行,在子表达式中挑出我们必须提取的片段。我假设 OX 前面正好有一个空格,它不能出现在输出中;可以根据需要进行调整。

    这假设所有以&gt; 开头的行都会有一个OS= ... 片段立即 后跟一个OX= ... 片段;如果没有,可以在s 命令之前将其添加到/&gt;/ 过滤器中。 (顺便说一句——在OS=...OX= ...之间可以有一些OT= ...片段吗?)

    问题——你不想在每行输出中包含一些标识符(可能是每行开头的“标签”的一部分)吗?你有你要求的碎片 - 但你知道它们每个来自哪里吗?

    【讨论】:

    • 问得好,但此时我很想知道它来自哪个物种。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    相关资源
    最近更新 更多