重新构建文件

时间:2016-11-19 12:40:03

标签: bash awk sed

我是编码的新手,但想使用awk,sed或bash来解决这个问题。 我有一个文件" input.txt"看起来像这样:

Otu13  k__Bacteria;p__Firmicutes;c__Bacilli;o__Lactobacillales;f__Streptococcaceae;g__Streptococcus        0.998
Otu24  k__Bacteria;p__Candidatus_Saccharibacteria;g__Saccharibacteria_genera_incertae_sedis; 1.000;; 
Otu59  k__Bacteria;p__Bacteroidetes;c__Bacteroidia;o__Bacteroidales;f__Prevotellaceae;g__Alloprevotella        0.991
Otu41  k__Bacteria;p__Bacteroidetes;g__Alloprevotella        0.998

首先,我想删除带有数字的最后一列,然后对于每行中的其余字段,根据它们的前缀(k__,p __,o__,f__,g__)将它们写出来。

前缀之后的值应以与括号中类似的顺序打印出来,这样如果序列顺序中的一个前缀丢失,例如第2行和第4行,然后将它们替换为空白。最后我应该有7个字段。

我想要的输出是这样的:

Otu13; Bacteria; Firmicutes; Bacilli; Lactobacillales; Streptococcaceae; Streptococcus
Otu24; Bacteria; Candidatus_Saccharibacteria; ; ; ;Saccharibacteria_genera_incertae_sedis
Otu59; Bacteria;Bacteroidetes;Bacteroidia;Bacteroidales;Prevotellaceae;Alloprevotella
Otu41; Bacteria;Bacteroidetes; ; ; ; Alloprevotella

非常感谢您的协助。

1 个答案:

答案 0 :(得分:2)

目前尚不清楚如何/为什么从您发布的输入中获得输出以及您的要求描述,但我认为这是您真正想要的:

$ cat tst.awk
BEGIN { n=split("k p c o f g",order); FS="[ ;]+|__"; OFS=";" }
{
    sub(/[0-9.;[:space:]]+$/,"")
    delete f
    for (i=2;i<=NF;i+=2) {
        f[$i] = $(i+1)
    }
    printf "%s%s", $1, OFS
    for (i=1; i<=n; i++) {
        printf "%s%s", f[order[i]], (i<n ? OFS : ORS)
    }
}

$ awk -f tst.awk file
Otu13;Bacteria;Firmicutes;Bacilli;Lactobacillales;Streptococcaceae;Streptococcus
Otu24;Bacteria;Candidatus_Saccharibacteria;;;;Saccharibacteria_genera_incertae_sedis
Otu59;Bacteria;Bacteroidetes;Bacteroidia;Bacteroidales;Prevotellaceae;Alloprevotella
Otu41;Bacteria;Bacteroidetes;;;;Alloprevotella