将Unix`cal`输出转换为乳胶表代码:单线解决方案?

Jo *_* So 5 bash shell perl awk sed

试图实现以下目标困扰我的想法:

将Unix cal输出转换为乳胶表代码,使用短而甜的单行(或几行).

例如cal -h 02 2012 | $magicline应该屈服

Mo      &Tu     &We     &Th     &Fr     \\
        &       & 1     & 2     & 3     \\
 6      & 7     & 8     & 9     &10     \\
13      &14     &15     &16     &17     \\
20      &21     &22     &23     &24     \\
27      &28     &       &       &       \\
Run Code Online (Sandbox Code Playgroud)

到目前为止,我能想出的唯一合理的解决方案是

cal -h | sed -r -e '1d' -e \
  's/^(..)?(...)?(...)?(...)?(...)?(...)?(...)?$/\2\t\&\3\t\&\4\t\&\5\t\&\6\t\\\\/'
Run Code Online (Sandbox Code Playgroud)

......我真的很努力.关于它的好处是,它简单易懂,易于理解,它是"不灵活"(它无法应付8周的一周)和一点点冗长.我正在寻找可供学习的替代解决方案;-)

编辑:找到另一个似乎可以接受的

cal -h | tail -n +2 |
    perl -ne 'chomp;
        $,="\t&";
        $\="\t\\\\\n";
        $line=$_;
        print map {substr($line,$_*3,3)} (1..5)'
Run Code Online (Sandbox Code Playgroud)

编辑:很好的一个:

cal -h | perl \
    -F'(.{1,3})' -ane \
        'BEGIN{$,="\t&";$\="\t\\\\\n"}
            next if $.==1;
            print @F[3,5,7,9,11]'
Run Code Online (Sandbox Code Playgroud)

Bir*_*rei 2

使用 GNU 版本awk

cal我使用 english的输出LANG

命令:

LANG=en_US cal
Run Code Online (Sandbox Code Playgroud)

输出:

    February 2012   
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29
Run Code Online (Sandbox Code Playgroud)

一行awk

LANG=en_US cal | awk '
BEGIN { 
  FIELDWIDTHS = "3 3 3 3 3 3 3"; 
  OFS = "&";
} 
FNR == 1 || $0 ~ /^\s*$/ { next } 
{ 
  for (i=2; i<=6; i++) { 
    printf "%-3s%2s", $i, i < 6 ? OFS : "\\\\";
  } 
  printf "\n";
}'
Run Code Online (Sandbox Code Playgroud)

结果:

Mo  &Tu  &We  &Th  &Fr \\
    &    & 1  & 2  & 3 \\
 6  & 7  & 8  & 9  &10 \\
13  &14  &15  &16  &17 \\
20  &21  &22  &23  &24 \\
27  &28  &29  &    &   \\
Run Code Online (Sandbox Code Playgroud)