awk将一列转置为多个具有空值的未知列

awk to transpose one column into multiple unknown columns with empty values

您好,我希望能够将一列转置为未知数量的列,如下所示。


--Before
c1 c2 c3 typ val
----------
H2|f|1|AQ|2
H2|f|1|MP|1
H2|f|3|MX|1
H1|c|3|MP|1
H1|c|3|MX|1

--after desired
c1 c2 c3 AQ MP MX 
---------
H2|f|1|2|1
H2|f|3|||1
H1|c|3||1|1

这是我的代码。它确实有效,但它会为 col1 col2 和 col3 的每个组合创建一行,即使这 3 列的特定组合没有关联值,如下所示。我可以简单地在最后删除空的,但我更担心这种方法的效率低下。

--output from my code with empty entries
c1 c2 c3 AQ MP MX 
---------
H2|f|1|2|1
H2|c|1||
H2|c|3||
H1|c|1||
H1|f|1||
H1|f|3||
H2|f|3|||1
H1|c|3||1|1

awk -F\| '
NR>0 {
    if(!( in ps)) { p[++types] =  }; ps[]++
    if(!( in es)) { e[++num1] =  }; es[]++
    if(!( in cs)) { c[++num2] =  }; cs[]++
    if(!( in ss)) { s[++num3] =  }; ss[]++
    map[,,,] = 
}
END {
    printf "%s;" ,"c1";
    printf "%s;" ,"c2";
    printf "%s;" ,"c3";
    for(prc=1; prc<=types; prc++) {
        printf "%s%s", sep, p[prc];
        sep = ";"
    }
    print "";
    sep = ";"
    for(coun1=1; coun1<=num1; coun1++) {
    for(coun2=1; coun2<=num2; coun2++) {
    for(coun3=1; coun3<=num3; coun3++) {
        printf "%s%s", sep, e[coun1]
        printf "%s%s", sep, c[coun2]
        printf "%s%s", sep, s[coun3]
        for(val=0; val<=types; val++) {
            printf "%s%s", sep, map[e[coun1],c[coun2],s[coun3], p[val]];
        }
        print ""
    }
    }
    }
}' $workfile


像这样的东西会起作用

$ awk -F'|' 'NR<3 {ps[NR]=[=10=]} 
             NR>2 {k= FS  FS ; h=; ks[k]; hs[h]; a[k,h]=}
             END  {split(ps[1],p," "); 
                   printf "%s %s %s", p[1],p[2],p[3]; 
                   for(h in hs) printf " %s",h; print "\n"ps[2]; 
                   for(k in ks) 
                      {printf "%s",k; 
                       for(h in hs) printf "%s%s",FS,a[k,h]; print ""}}' file

c1 c2 c3 MP AQ MX
----------
H2|f|1|1|2|
H2|f|3|||1
H1|c|3|1||1

请注意,此方法不能保证列顺序,如果重要,则需要一些额外的簿记。此外,您的 header 字段分隔符与数据部分不匹配,似乎是一个需要处理的问题。