多维数组 - AWK 中的数据透视表



我需要将元素从数组转换为列索引,并为每个列索引返回 $3 的值。我无法访问 gawk 4,所以我无法使用真正的多维数组。

输入

Name^Code^Count
Name1^0029^1  
Name1^0038^1   
Name1^0053^1  
Name2^0013^3  
Name2^0018^3  
Name2^0023^5  
Name2^0025^1  
Name2^0029^1  
Name2^0038^1  
Name2^0053^1  
Name3^0018^1  
Name3^0060^1  
Name4^0018^2  
Name4^0025^5  
Name5^0018^2  
Name5^0025^1  
Name5^0060^1

期望的输出

Name^0013^0018^0023^0025^0029^0038^0053^0060
Name1^^^^^1^1^1^  
Name2^3^3^5^1^1^1^1^  
Name3^^1^^^^^^1  
Name4^^2^^5^^^^  
Name5^^^^1^^^^1 

关于如何在不使用真正的多维数组的情况下处理此任务的任何建议?

以下解决方案使用GNU awk v3.2功能进行排序。这不使用多维数组。它只模拟一个。

awk -F"^" '
NR>1{
    map[$1,$2] = $3
    name[$1]++
    value[$2]++
}
END{
    printf "Name"
    n = asorti(value, v_s)
    for(i=1; i<=n; i++) {
        printf "%s%s", FS, v_s[i]
    }
    print ""
    m = asorti(name, n_s)
    for(i=1; i<=m; i++) { 
        printf "%s", n_s[i]
        for(j=1; j<=n; j++) { 
            printf "%s%s", FS, map[n_s[i],v_s[j]]
        }
        print ""
    }
}' file
Name^0013^0018^0023^0025^0029^0038^0053^0060
Name1^^^^^1^1^1^
Name2^3^3^5^1^1^1^1^
Name3^^1^^^^^^1
Name4^^2^^5^^^^
Name5^^2^^1^^^^1

这将适用于任何 awk,并将按数字顺序对计数的输出进行排序,同时保持名称在输入文件中出现的顺序:

$ cat tst.awk
BEGIN{FS="^"}
NR>1 {
    if (!seenNames[$1]++) {
        names[++numNames] = $1
    }
    if (!seenCodes[$2]++) {
        # Insertion Sort - start at the end of the existing array and
        # move everything greater than the current value down one slot
        # leaving open the slot for the current value to be inserted between
        # the last value smaller than it and the first value greater than it.
        for (j=++numCodes;codes[j-1]>$2+0;j--) {
            codes[j] = codes[j-1]
        }
        codes[j] = $2
    }
    count[$1,$2] = $3
}
END {
    printf "%s", "Name"
    for (j=1;j<=numCodes;j++) {
        printf "%s%s",FS,codes[j]
    }
    print ""
    for (i=1;i<=numNames;i++) {
        printf "%s", names[i]
        for (j=1;j<=numCodes;j++) {
            printf "%s%s",FS,count[names[i],codes[j]]
        }
        print ""
    }
}

$ awk -f tst.awk file
Name^0013^0018^0023^0025^0029^0038^0053^0060
Name1^^^^^1^1^1^
Name2^3^3^5^1^1^1^1^
Name3^^1^^^^^^1
Name4^^2^^5^^^^
Name5^^2^^1^^^^1

由于您只有两个"维度",因此很容易为每个维度使用一个数组和一个具有计算列名的连接数组。 我没有对列或行进行排序,但这个想法非常基本。

#!/usr/bin/awk -f
#
BEGIN { FS = "^" }
(NR == 1) {next}
{
    rows[$1] = 1
    columns[$2] = 1
    join_table[$1 "-" $2] = $3
}
END {
    printf "Name"
    for (col_name in columns) {
        printf "^%s", col_name
    }
    printf "n"
    for (row_name in rows) {
        printf row_name
        for (col_name in columns) {
            printf "^%s", join_table[row_name "-" col_name]
        }
        printf "n"
    }
}

相关内容

  • 没有找到相关文章

最新更新