使用awk在fasta标题中的分隔符后保留文本

时间:2015-02-23 18:32:53

标签: bash awk fasta

我有一个应该是一个简单的问题,但我缺乏awk知识阻碍了我。

我想清理这种格式的fasta文件的标题:

>HWGG454_Clocus2_Locus3443_allele1
ATTCTACTACTACTCT
>GHW757_clocus37_Locus555662_allele2
CTTCCCTACGATG
>TY45_clocus23_Locus800_allele0
TTCTACTTCATCT

我想清理每个标题(以“>”开头的行)以仅保留信息部分,这是第二个带有或不带等位基因部分的“_Locus *”。

我认为awk是这样做的简单方法,但我不能让它工作。

如果我想保留第一列文本到标题的“_”分隔符以及下面的序列,我运行它(假设这个玩具示例在文件test.fasta中):

 cat test.fasta | awk -F '_' '{print $1}'

>HWGG454
ATTCTACTACTACTCT
>GHW757
CTTCCCTACGATG
>TY45
TTCTACTTCATCT

但是,我想要的只是保留“Locus *”文本,这是在第3个分隔符之后,但是,使用这个代码我得到了这个:

cat test.fasta | awk -F '_' '{print $3}'
Locus3443

Locus555662

Locus800

我在这里做错了什么?

感谢。

4 个答案:

答案 0 :(得分:1)

我理解这意味着您要从标题行中选择Locus字段并保持其他字段不变。然后:

awk -F _ '/^>/ { print $3; next } 1' filename

也许是最简单的方法。其工作原理如下:

/^>/ {      # in lines that begin with >
  print $3  # print the third field
  next      # and go to the next line.
}
1           # print other lines unchanged. Here 1 means true, and the
            # default action (unchanged printing) is performed.

这里要理解的是awk的控制流:awk代码由具有相关操作的条件组成,如果条件的计算结果为true,则执行操作。

/^>/是整个记录的正则表达式匹配(默认为行);如果该行以>开头(因为^与开头匹配),则为真,所以

/^>/ { print $3; next }

将使awk在以print $3; next开头的行中执行>。不太直白的部分是

1

打印线不变。如果没有执行第一个操作(因为其中包含next),我们才会到达此处,并且此1将被视为始终为真的条件 - 非零值在awk中为真

现在,如果省略了awk语句中的条件或操作,则使用默认值。默认操作是打印行不变,这利用了它。编写

同样是可能的
1 { print }

{ print }

在后一种情况下,条件被省略,默认条件为" true"用来。 1是这个的最短变体,也是因为它的惯用语。

答案 1 :(得分:1)

$ awk -F_ '{print (/^>/ ? $3 : $0)}' file
Locus3443
ATTCTACTACTACTCT
Locus555662
CTTCCCTACGATG
Locus800
TTCTACTTCATCT

答案 2 :(得分:0)

您需要为下面的行添加第二个awk匹配项。 e.g。

cat test.fasta | awk -F _ '/^>/ { print $3"_"$4 } /^[A-Z]/ {print $1}'

输出:

Locus3443_allele1
ATTCTACTACTACTCT
Locus555662_allele2
CTTCCCTACGATG
Locus800_allele0
TTCTACTTCATCT

如果您不希望_allele1位从awk脚本中删除"_"$4

答案 3 :(得分:0)

你可以在每一行上做一个正则表达式:

$ awk '{ sub(/^.*_L/,"L"); print $0}' /tmp/fasta.txt
Locus3443_allele1
ATTCTACTACTACTCT
Locus555662_allele2
CTTCCCTACGATG
Locus800_allele0
TTCTACTTCATCT