Text-Processing

在 bash 中使用 cal 函式選擇“第一個”日期

  • December 8, 2018

cal我試圖從函式和管道awk命令中挑選出第一個星期一、第二個星期二、第二個星期六等。對於這個月,我可以使用日曆下方的命令正確獲取第一個星期二:

   December 2018
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
30 31

>cal | awk 'NF == 7 && NR > 2 {print $3; exit}'
>4

但這並不總是有效,請參閱下面 2016 年 3 月的測試:

    March 2016
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 30 31

>cal 3 2016 | awk 'NF == 7 && NR > 2 {print $3; exit}'
>8

為什麼它適用於頂部範例而不適用於底部範例?我認為底部範例應該查看第三行並找到正確的結果1。是否有一種萬無一失的方法來使用這些日期awk- 也許檢查該列是否為空並移動到下一行?

這是您的另一種解決方案

cal | awk 'NR >= 3 { tu = substr($0,7,2) +0 } tu { print tu; exit }'
4

cal 3 2016 | awk 'NR >= 3 { tu = substr($0,7,2) +0 } tu { print tu; exit }'
1

它挑選出星期二列(字元 7 和 8),並提供第一個非零值。該方法可以安全地外推到一周中的任何一天。

使用 GNU 日期:

對於當月的第一個星期二:

for day in 0{1..7}; do [[ "$(date -d $(date +%Y%m${day}) +%a)" = "Tue" ]] && echo "$day";done

對於給定年份和月份的第一個星期二:

year=2016
month=03
for day in 0{1..7}; do [[ "$(date -d ${year}${month}${day} +%a)" = "Tue" ]] && echo "$day";done

awk 的“星期二”變體:

cal | awk -F "" '!/[[:alpha:]]/ && $7$8 ~ /[0-9]/ { print $7$8;exit }'

這將檢查輸出中第 7 列和第 8 列(星期二)的硬編碼位置(注意欄位分隔符為空,將輸入拆分為每個字元)——在跳過任何包含字母的行(標題行)之後。調整 7 和 8 以獲得其他日期。

為了更清楚前面的命令在做什麼,awk 命令的欄位按列編號:

123456789            <--- awk fields $1, $2, $3, ... $9
   December 2018
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
30 31

引用自:https://unix.stackexchange.com/questions/486656