今回は、GNU date を使って月末の日付を得る方法について。 シェルスクリプトで一ヶ月単位の処理を書こうとすると、よく調べることになるのでメモしておく。
検証に使った環境は次のとおり。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H15 $ date --version date (GNU coreutils) 8.32 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by David MacKenzie.
もくじ
下準備
検証に使ったのは macOS で、デフォルトでは date(1) が BSD date になっている。 GNU date の方がオプションが多彩で扱いやすいので入れ替えよう。 Homebrew で Coreutils を入れると gdate というコマンドで GNU date が使えるようになる。
$ brew install coreutils
$ alias date=gdate
GNU date の使い方
GNU date では +
以降にフォーマット文字列を指定することで日時を整形できる。
使えるフォーマット文字列は man 1 gdate
を参照のこと。
たとえば、次のようにすれば年月日をハイフンでつないだフォーマットで今日の日付を表示できる。
$ date '+%Y-%m-%d'
2020-11-13
先ほどの実行結果を見てわかるとおり、デフォルトでは表示される内容として現在の日時が使われる。
これは --date
オプションに now
を指定していることに等しい。
$ date '+%Y-%m-%d' --date 'now' 2020-11-13
--date
オプションは Human readable なフォーマットを受け付けるようになっている。
たとえば 1 month
を指定すると、現在の 1 ヶ月後になる。
$ date '+%Y-%m-%d' --date '1 month' 2020-12-13
他にも、1 day ago
や yesterday
とすれば昨日が得られる。
$ date '+%Y-%m-%d' --date '1 day ago' 2020-11-12 $ date '+%Y-%m-%d' --date 'yesterday' 2020-11-13
それ以外のテクニックとして、日時をずらした上でフォーマットを駆使して意図した内容を得ることもできる。 たとえば、月初の日付がほしいなら、フォーマットの日付を 1 日にしてやれば良い。 以下では、来月の 1 日の日付を取得している。
$ date '+%Y-%m-01' --date '1 month' 2020-12-01
月末の日付を得る
さて、それでは今回の本題に入る。
たとえば、ここまでの要領で「今月末の日付」を得るには「来月の 1 日の 1 日前」を計算してやれば良いことになる。
これを一回の date(1) の実行で得るのは難しいので、インラインコマンドを駆使する。
つまり、まずは「来月の 1 日」を得た上で、それを次の date(1) の --date
オプションに埋め込んでやる。
$ date '+%Y-%m-%d' --date "1 day ago $(date '+%Y-%m-01' --date '1 month')" 2020-11-30
ちゃんと今月末の日付が得られた。
次に、任意の月の月末の日付がほしいなら、インラインで実行する date(1) の --date
オプションにその月の日付を指定すれば良い。
たとえば、以下では 2020 年 2 月の末日を取得している。
今年はうるう日があった。
$ date '+%Y-%m-%d' --date "1 day ago $(date '+%Y-%m-01' --date '1 month 2020-02-01')" 2020-02-29
めでたしめでたし。
- 作者:もみじあめ
- 発売日: 2020/02/29
- メディア: Kindle版