awk:格式化 awk 脚本中 table 数据的顺序

Awk: Formatting the order of table data in awk script

我有以下输出文件。请注意,此数据是动态的,因此可能会有或多或少的年份和更多类别 A、B、C、D...:[=​​14=]

    2015    2016    2017

EX

FE
B   0.00    -2.00   -1.00
D   0.00    -1.00   0.00
sumFE   0.00    -3.00   -1.00

VE
B   0.00    -3.00   0.00
C   -4.00   0.00    0.00
D   0.00    -5.00   0.00
sumVE   -4.00   -8.00   0.00

sumE    -4.00   -11.00  -1.00

IN

FI
A   8.00    0.00    0.00
C   0.00    0.00    8.00
sumFI   8.00    0.00    8.00

VI
A   0.00    0.00    5.00
B   4.00    0.00    0.00
sumVI   4.00    0.00    5.00

sumI    12.00   0.00    13.00

net 8.00    -11.00  12.00

我正在尝试这样格式化它。

    2015    2016    2017

IN

VI
A   0.00    0.00    5.00
B   4.00    0.00    0.00
sumVI   4.00    0.00    5.00

FI
A   8.00    0.00    0.00
C   0.00    0.00    8.00
sumFI   8.00    0.00    8.00

sumI    12.00   0.00    13.00

EX

VE
B   0.00    -3.00   0.00
C   -4.00   0.00    0.00
D   0.00    -5.00   0.00
sumVE   -4.00   -8.00   0.00

FE
B   0.00    -2.00   -1.00
D   0.00    -1.00   0.00
sumFE   0.00    -3.00   -1.00

sumE    -4.00   -11.00  -1.00

net 8.00    -11.00  12.00

我试过以下脚本作为开始:

#!/usr/bin/env bash
  
awk '

BEGIN{FS="\t"}

3>NR {print "D" [=13=]}

 ~ /^I$/, ~ /^sumI$/ {
        print
}

 ~ /^E$/, ~ /^sumE$/{
        print
}

 ~ /net/ {print ORS [=13=]}

' "${@:--}"

该脚本在将所有 I 数据替换为 E 数据方面大有帮助,但执行顺序未保留,最后打印出 I 块。有人可以帮忙吗。

这可能会更容易修改原始代码以使用 GNU awk's predefined array scanning orders。关键 objective 是在关联的 for (index in array) 循环之前切换扫描顺序 (PROCINFO["sorted_in"])。

添加四行代码(参见 # comments)我猜是 :

...
END {
    for (year = minYear; year <= maxYear; year++) {
        printf "%s%s", OFS, year
    }
    print ORS
    PROCINFO["sorted_in"]="@ind_str_desc"                           # sort cat == { I | E } in descending order
    for (cat in ctiys2amounts) {
        printf "%s\n\n",(cat=="I") ? "IN" : "EX"                    # print { IN | EX }
        delete catSum
        PROCINFO["sorted_in"]="@ind_str_desc"                       # sort type == { VI | FI } || { VE | FE } in descending order
        for (type in ctiys2amounts[cat]) {
            print type
            delete typeSum
            PROCINFO["sorted_in"]="@ind_str_asc"                    # sort item == { A | B | C | D } in ascending order
            for (item in ctiys2amounts[cat][type]) {
                printf "%s", item
                for (year = minYear; year <= maxYear; year++) {
                    amount = ctiys2amounts[cat][type][item][year]
                    printf "%s%0.2f", OFS, amount
                    typeSum[year] += amount
                }
                print ""
            }
....

这会生成:

        2015    2016    2017

IN

VI
A       0.00    0.00    5.00
B       4.00    0.00    0.00
sumVI   4.00    0.00    5.00

FI
A       8.00    0.00    0.00
C       0.00    0.00    8.00
sumFI   8.00    0.00    8.00

sumI    12.00   0.00    13.00

EX

VE
B       0.00    -3.00   0.00
C       -4.00   0.00    0.00
D       0.00    -5.00   0.00
sumVE   -4.00   -8.00   0.00

FE
B       0.00    -2.00   -1.00
D       0.00    -1.00   0.00
sumFE   0.00    -3.00   -1.00

sumE    -4.00   -11.00  -1.00

net     8.00    -11.00  12.00