我碰到这一行 脚本用于删除固定宽度文本文件中的换行符。这个想法是更改一个充满条目的文件,例如:
>IGHV1-18*01
CAGGTTCAGCTGGTGCAGTCTGGAGCTGAGGTGAAGAAGCCTGGGGCCTCAGTGAAG
GTCTCCTGCAAGGCTTCTGGTTACACCTTTACCAGCTATGGTATCAGC
TGGGTGCGACAGGCCCCTGGACAAGGGCTTGAGTGGATGGGATGGATCAGCGCTTAC
AATGGTAACACAAACTATGCACAGAAGCTCCAGGGCAGAGTCACCATGACCACA
GACACATCCACGAGCACAGCCTACATGGAGCTGAGGAGCCTGAGATCTGACGACACGGCC
GTGTATTACTGTGCGAGAGA
到
>IGHV1-18*01
CAGGTTCAGCTGGTGCAGTCTGGAGCTGAGGTGAAGAAGCCTGGGGCCTCAGTGAAGGTCTCCTGCAAGGCTTCTGGTTACACCTTTACCAGCTATGGTATCAGCTGGGTGCGACAGGCCCCTGGACAAGGGCTTGAGTGGATGGGATGGATCAGCGCTTACAATGGTAACACAAACTATGCACAGAAGCTCCAGGGCAGAGTCACCATGACCACAGACACATCCACGAGCACAGCCTACATGGAGCTGAGGAGCCTGAGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGA
我对 AWK 的经验不是很丰富,所以我认为尝试和解读它会是一次很好的学习经历。然而,我遇到了困难。具体来说,关于多个块相继出现,第一个块是隐式 for 循环吗?
awk '/^>/ {printf("\n%s\n",$0);next; } { printf("%s",$0);} END {printf("\n");}' < file.fa
答案1
有点,是的。只是它不是隐含的。其格式实际上是:
/foo/{something}
哪个是相同的
if(/foo/){something}
换句话说,如果当前行匹配foo
(在您的示例中,如果它匹配>
),则打印换行符、当前行和另一个换行符。
确保next
如果执行第一个块,脚本将跳过其余块并移至下一行。 oneliner 也可以这样写:
awk '{
if(/^>/){
printf("\n%s\n",$0);
}
else{
printf("%s",$0);
}
END {
printf("\n");
}' < file.fa
最后,由于简单的print
调用awk
添加了换行符,因此您可以使用上面的稍微简单的版本:
awk '/^>/{print "\n"$0;next;}{printf("%s",$0);} END{print}' file.fa
答案2
awk 将逐行读取(您可能认为是一个块,但它是一行,以换行符或 CR 结尾)
让我们破解该代码
awk '/^>/ {printf("\n%s\n",$0);next; } { printf("%s",$0);} END {printf("\n");}'
正如您在 中所看到的man awk
,awk 程序的形式为/pattern/ { actions}
,因此程序变为:
/^>/ {printf("\n%s\n",$0);next; }
>
对于以(/^>/
)开头的行\n
打印(printf("\n%s\n",$0)
)包围的行- 获取下一行 (
next
),不转到下一个 awk 命令。
{ printf("%s",$0);}
- 对于所有模式(模式子句为空)
- 打印不带换行符的行 (
printf("%s",$0);
)
END {printf("\n");}
- 在文件(或多个文件)结束之后(
END
) - 打印换行符 (
printf "\n" ;
)
- 在文件(或多个文件)结束之后(