AWK 中的多个块如何工作?

AWK 中的多个块如何工作?

我碰到这一行 脚本用于删除固定宽度文本文件中的换行符。这个想法是更改一个充满条目的文件,例如:

>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" ;)

相关内容