Bashのcal関数を使用して「最初の」日付を選択します。

Bashのcal関数を使用して「最初の」日付を選択します。

cal関数とパイプコマンドawkで、最初の月曜日、2番目の火曜日、2番目の土曜日などを選択しようとしています。今月は受け取ることができます。最初の火曜日次のカレンダーコマンドを正しく使用してください。

    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

上の例では機能しますが、下の例では機能しないのはなぜですか?私の考えでは、次の例は3行目を見て正しい結果を見つける必要があると思います1。私が使用できる確実な方法はありますかawk?列が空であることを確認し、次の行に移動してこの日付を取得できますか?

答え1

ここにあなたのための別の解決策があります

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)を選択し、ゼロ以外の最初の値を指定します。この方法は、どの曜日でも安全に推定できます。

答え2

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 }'

次に、文字(タイトルOK)を含む行をスキップする前に、列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

答え3

gcal(GNU) と (BSD) シリーズはどちらもncal行と列を置き換えるオプションをサポートしています。

$ ncal
    March 2024        
Su     3 10 17 24 31
Mo     4 11 18 25   
Tu     5 12 19 26   
We     6 13 20 27   
Th     7 14 21 28   
Fr  1  8 15 22 29   
Sa  2  9 16 23 30   

$ gcal -i

March 2024

Sunday          3 10 17 24 31
Monday          4 11 18 25   
Tuesday         5 12 19 26   
Wednesday       6 13 20 27   
Thursday        7 14 21 28   
Friday       1  8 15 22 29   
Saturday     2  9 16 23 30   

このように呼び出すと、曜日ごとに順次位置を選択する方が簡単です。まずawk、目的の曜日に一致するパターンを使用してから、N-1列を印刷してその曜日のN番目のインスタンスを取得します。

たとえば、特定の月と年の最初の火曜日は次のようになります。

$ ncal 12 2018 | awk '/^Tu/ { print $2; }'
4
$ ncal 3 2016 | awk '/^Tu/ { print $2; }'
1

毎月5番目の金曜日を得るには(正確に1つの金曜日があります):

$ ncal | awk '/^Fr/ { print $6; }’
29

答え4

ksh93から:

$ printf '%(%F)T\n' 'first monday this month'
2024-03-04
$ printf '%(%F)T\n' 'second tuesday this month'
2024-03-12
$ printf '%(%F)T\n' '2nd tuesday in 2016-03'
2016-03-08

(知っている4番目と5番目は現在ksh93u + mバージョンでは機能しません。;それにもかかわらfourthfifth)。

関連情報