2015-02-23 32 views
1

我有什么应该是一个简单的问题,但是我缺乏awk知识让我失望。在使用awk的fasta头文件中的分隔符后保留文本

我想清理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 

但是,我要的是留住只是“轨迹*”的文字,这是第3次分隔符之后,但是,使用这种代码我得到这个:

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

Locus555662 

Locus800 

我在做什么错在这里?

谢谢。

+0

什么是您预期的输出? – anubhava 2015-02-23 18:37:19

回答

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代码由具有关联操作的条件,如果条件计算为真执行的操作。

/^>/是整个记录的正则表达式匹配(默认为行);它是真实的,如果符合>(因为^比赛开始时)开始,所以

/^>/ { print $3; next } 

将AWK在与>开头的行执行print $3; next。不那么简单的部分是

1 

其中打印行不变。如果第一个动作未被执行(因为其中的next),并且此1将被视为始终为真的条件 - 非awk中的非零值为true。

现在,如果省略了awk语句中的条件或操作,则使用默认值。默认的操作是不改变地打印行,并且这利用了它。它也同样可以写

1 { print } 

{ print } 

在后者的情况下,省略了条件和默认条件“真”被使用。1是这个的最短变体,因为它的原因。

0

您需要第二个awk匹配下面的行。例如

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

输出:

Locus3443_allele1 
ATTCTACTACTACTCT 
Locus555662_allele2 
CTTCCCTACGATG 
Locus800_allele0 
TTCTACTTCATCT 

如果你不想_allele1位从awk脚本删除"_"$4

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

最''awkish' – 2015-02-24 15:07:08

0

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

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