1 ヶ月カレンダー
awk で作られたカレンダーのプログラムを探していたのですが、見つからなかったので、自分で作ってみました。 cal コマンドのような指定ができますが、1 ヶ月分しか表示しません。 また、gawk の mktime() 関数や strftime() 関数を多用しているため、gawk, xgawk のみの動作となっています、
#! /usr/local/bin/gawk -f
# cal.awk
# カレンダーを表示する
# usage: gawk -f cal.awk [[month] year]
BEGIN {
# オプションの設定
year = (ARGV[1] && ARGV[2]) ? ARGV[2] : ARGV[1] ? ARGV[1] : strftime("%Y");
month = (ARGV[1] && ARGV[2]) ? ARGV[1] : strftime("%m");
month = sprintf("%02d", month);
month_days = "31 28 31 30 31 30 31 31 30 31 30 31 ";
split(month_days, arr_days);
# うるう年の計算
leap = (year % 400 == 0) ? 1 : (year % 100 == 0) ? 0 : (year % 4 == 0) ? 1 : 0;
# うるう年の場合に 2 月を 29 日にする
if (leap == 1) {
arr_days[2] = 29;
}
# タイトル部分の印字
print " " year " / " month;
print "SU MO TU WE TH FR SA";
# その月の最初 1 日が何曜日かによってスペースを加える
for (i = 0; i < strftime("%w", mktime(year " " month " 1 12 00 00")); i++) {
space = space " ";
}
printf("%s", space);
# その月の日数だけループ
for (i = 1; i <= arr_days[month + 0]; i++) {
# 日曜日の場合に改行する
if (strftime("%w", mktime(year " " month " " i " 12 00 00")) == 0 &&
i != 1) {
print "";
}
printf("%2d ", i);
}
print "";
}
故意に条件演算子 (三項演算子) を使っているため、短く収まっていますが、少し分かりにくくなっています。
$ gawk -f cal.awk # <- 今月のカレンダーです
2009 / 06
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
$ gawk -f cal.awk 2010 # <- 2010 年の同じ月のカレンダーです
2010 / 06
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
$ gawk -f cal.awk 1 2010 # <- 2010 年の 1 月のカレンダーです
2010 / 01
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
うるう年の判定は閏年 - jarp, あたりのものを使っても面白いかもしれませんが、条件演算子で判定しています。
cal コマンドの代用というよりは、ブログなどのパーツとして使えるかなと思い、1 ヶ月分の表示しかしていません。


