我有一个应该是一个简单的问题,但我缺乏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
我在这里做错了什么?
感谢。
答案 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