awk:将列 header 转置为行的第一个字段

awk: transpose column header to first field of row

我的输入是这样的:

A|B|C
1|2|3
4|5|6

使用 awk,我试图获得:

A|1
B|2
C|3
A|4
B|5
C|6

我的代码:

gawk '
BEGIN{FS=OFS="|"}
NR==1{
    for(i=1; i<=NF; i++){
        x_i=$i
    }
}
NR>1{
    for(i=1; i<=NF; i++){
        print x_i FS $i
    }
}' input  

但它只保留 NR==1 块的最后一次迭代,即使我在 NR>1 块中使用相同的循环也是如此:

C|1
C|2
C|3
C|4
C|5
C|6

有什么技巧吗?

编辑

感谢 Jose,我需要将 x_i 更改为 x[i]

如果使用相同的输入,我需要输出:

A;B;C|1|2|3
A;B;C|4|5|6

你可以试试,

awk 'BEGIN{FS=OFS="|"}
     NR==1{for(i=1; i<=NF; ++i) d[i]=$i; next}
     {for(i=1; i<=NF; ++i) print d[i], $i}
' input

你得到

A|1
B|2
C|3
A|4
B|5
C|6

重要提示

你的逻辑是正确的,只是x[i]而不是x_i

gawk '
BEGIN{FS=OFS="|"}
NR==1{
    for(i=1; i<=NF; i++){
        x[i]=$i
    }
}
NR>1{
    for(i=1; i<=NF; i++){
        print x[i] FS $i
    }
}' input
$ awk 'BEGIN{FS=OFS="|"} NR==1{split([=10=],h);next} {for (i=1;i<=NF;i++) print h[i], $i}' file
A|1
B|2
C|3
A|4
B|5
C|6

$ awk 'BEGIN{FS=OFS="|"} NR==1{gsub(/\|/,";");h=[=10=];next} {print h, [=10=]}' file
A;B;C|1|2|3
A;B;C|4|5|6

阅读 Effective Awk Programming,第 4 版,作者 Arnold Robbins。

这是另一个使用 splitfor:

$ awk 'NR==1 { split([=10=],a,"|") } 
       NR>1  { n=split([=10=],b,"|");
              for(i=1;i<=n;i++) 
                  print a[i] "|" b[i] }' file
A|1
B|2
C|3
A|4
B|5
C|6