BLOGサブスレッドの日常

2017.09.29

シェルスクリプトで期間を指定して yyyymmdd のカンマ区切りのリストを作る

chao

はじめに

しみずです。どうぞよろしく。

先日、インプラントの手術をしたんですけど、途中で麻酔が切れてきてしまって
骨にドリルで穴を空けるときになかなか痛かった。
追加で麻酔打ったら痛くなくなったので麻酔って凄いと思いました。

アプリやサーバのログを yyyymmdd の命名規則で日付ごとに出力している事とかあると思います。
で、期間を指定してコマンドラインから何らかの集計をしたい場合、ファイル名一つ一つ指定するのも辛いので
開始日と終了日を指定してカンマ区切りのリストを作ったら、ブレース展開に使えて便利だよね。
と思ったので、考えてみました。

※ブレース展開について、詳しくはこちら。
http://www.subthread.co.jp/blog/20170718/

確認環境

iMac
OS X El Capitan 10.11.6
bash

実現する方法を考える

まずは実現する方法を考えます。
入力される期間も yyyymmdd 形式にします。

数字を単純にインクリメントしていくだけだと、8/31 の後に、9/1 にできません。
ので、日付として扱うことができないか考えます。

日付にしたら、その日付にプラス1日して次の日を得る方法を考えます。

最後に、プラス1した日付取得を期間の終了日までループで回せば、リストを作ることができそうです。

まとめるとこんな感じ。

  1. yyyymmdd 形式を日付として扱う方法を調べる
  2. その日付にプラス1日した日付を得る方法を調べる
  3. 終了日までループで回す

yyyymmdd 形式を日付として扱う

yyyymmdd 形式を日付として扱うのは、date コマンドが使えそうでした。

例えば、本日の日付 20170928 を date コマンドで扱うにはこんな感じ。

date -j -f %Y%m%d 20170928 +%Y-%m-%d
# 結果:2017-09-28

このように入力フォーマットと出力フォーマットを指定することができます。

-j がPCの日付を設定せず出力のみ行うオプション。
-f が入力フォーマット指定のオプション。
最後の +%Y-%m-%d が出力フォーマットです。

日付にプラス1日した日付を得る

date コマンドで日付を扱えたので、日付をプラス1日する方法を考えます。
これも date コマンドのオプションに指定する事で出力結果をプラス1日することができるようです。
月末の 20170930 にプラス1日してみましょう。

date -j -v+1d -f %Y%m%d 20170930 +%Y%m%d
# 結果:20171001

ちゃんと10月1日が取得できました。
-v オプションで入力した日付から増減した値を出力できます。
1日したい場合は +1d を追加して -v+1d にします。

これで、プラス1日した日付を取得する事ができました。

終了日までループで回す

あとは、終了日までループするだけです。
開始日、終了日は変数として定義しておきます。
変数でプラス1日した値を覚えておいて、次にその値を使ってプラス1する。というのを繰り返せば良さそうです。
2017/09/20 〜 2017/10/10 までを出力してみましょう。

START_DATE=20170928
END_DATE=20171010
current=$START_DATE
while [ "$current" != "$END_DATE" ]
do
    current=`date -j -v+1d -f %Y%m%d $current +%Y%m%d`
    echo $current
done

これを period.sh とでも付けて保存します。
このスクリプトを実行してみましょう。
(ファイルに実行権限を付けるのを忘れずに。 chmod +x period.sh でいけます)

./period.sh
20170929
20170930
20171001
20171002
20171003
20171004
20171005
20171006
20171007
20171008
20171009
20171010

こんな感じで出力されました。

カンマ区切りのリストにする

結果を変数に覚えておいてつなぎ合わせていけば良さそうです。
period という変数を用意してそこに入れていきます。

START_DATE=20170928
END_DATE=20171010
current=$START_DATE
period=$current
while [ "$current" != "$END_DATE" ]
do
    current=`date -j -v+1d -f %Y%m%d $current +%Y%m%d`
    period="$period,$current"
done

echo $period

実行するとカンマ区切りのリストが period に入っているのが確認できます。

./period.sh
20170928,20170929,20170930,20171001,20171002,20171003,20171004,20171005,20171006,20171007,20171008,20171009,20171010

おわりに

このリストを作ることで、yyyymmdd 形式のファイル名で取っているログとかを集計するのに
期間指定が行えるようになって便利です。
カンマ区切りになっているので、ブレース展開が使えます。

※ブレース展開について、詳しくはこちら。
http://www.subthread.co.jp/blog/20170718/
(謎のブレース展開推し)

この記事を書いた人

chao