将列表转置为表格格式(awk)

时间:2014-06-13 16:07:27

标签: bash shell unix awk ksh

我希望将包含一周中几天的列表与其旁边的时间转换为格式化的表格。

输入如下:

Mon 0100
Mon 0700
Tue 0700
Wen 0100
Wen 0700
Thu 0100
Thu 0700
Fri 0100
Fri 0700
Sat 0100
Sun 0100
Sun 0700

输出如下:

        Mon  Tue  Wed  Thu  Fri  Sat  Sun   
0100    X         X    X    X    X    X   
0700    X    X    X    X    X         X    

在awk中寻找理想的答案。在给出的输出中保留格式是优选的。在不存在工作日的情况下,不应该包括它(如果可能的话,如果输入中不存在,那么输出中包含丢失的工作日的答案也会很好。

我给了它一个镜头,但除了打印第一行之外,我真的无法理解数组的构造,即使我认为它相对简单。

由于 埃尔

2 个答案:

答案 0 :(得分:5)

以下是使用awk的一种方式:

awk '
!($1 in day) { days[++d] = $1; day[$1]++ }
!($2 in num) { nums[++n] = $2; num[$2]++ }
             { map[$1,$2]++ }
END {
    printf "\t"
    for (i=1; i<=d; i++) {
        printf "\t%s", days[i]
    }
    print ""
    for (j=1; j<=n; j++) {
        printf "%s ", nums[j]
        for (i=1; i<=d; i++) {
            printf "\t%s", (map[days[i],nums[j]] ? "X" : FS )
        }
        print ""
    }
}' file

输出:

        Mon Tue Wen Thu Fri Sat Sun
0100    X       X   X   X   X   X
0700    X   X   X   X   X       X

答案 1 :(得分:1)

我确信有一个更优雅的解决方案(我真的不知道awk - 只是去了gawk manual):

BEGIN {
        days["Mon"] = 1      
        days["Tue"] = 2      
        days["Wen"] = 4      
        days["Thu"] = 8      
        days["Fri"] = 16      
        days["Sat"] = 32      
        days["Sun"] = 64      
}

{
        hours[$2] = or(hours[$2], days[$1])
}

END {
        print "        Mon  Tue  Wed  Thu  Fri  Sat  Sun"

        for (key in hours) {
                printf "%s    ", key
                for (i = 0; i < 7; i++) {
                        if (and(hours[key], 2 ** i))
                                printf "X"
                        else
                                printf " "
                        printf "    "
                }
                print ""
        }
}

请注意,在您的示例输入文件中,星期三是&#34; Wen&#34;但在你的输出中它是&#34;星期三。&#34;如果您的样本输入文件有拼写错误,则需要更改上面脚本的第4行以匹配。