【问题标题】:Transpose list to tablular format (awk)将列表转置为表格格式 (awk)
【发布时间】:2014-08-04 06:26:48
【问题描述】:

我希望将包含星期几的列表及其旁边的时间转换为类似格式的表格。

在下方输入:

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 中寻找答案。在给定的输出中保留格式是首选。在工作日不存在的情况下,不应该包括它(如果可能的话,如果输入中不存在缺少的工作日,那么最好也有答案,其中包括输出中缺少的工作日)。

我试了一下,但除了打印第一行之外,我真的无法理解数组的构造,尽管我认为它相对简单。

谢谢 艾尔

【问题讨论】:

    标签: bash shell unix awk ksh


    【解决方案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 ""
            }
    }
    

    请注意,在您的示例输入文件中,星期三是“Wen”,但在您的输出中是“Wed”。如果示例输入文件中有您的拼写错误,您需要更改上面脚本的第 4 行以匹配。

    【讨论】:

      【解决方案2】:

      这是使用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
      

      【讨论】:

      • 真的很棒。即使是 awk 的新手,我也可以完全理解这段代码。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2021-03-22
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      相关资源
      最近更新 更多