APIを使った独自シェルをつくろう(祝日付きカレンダーcal3・天気情報wx)
祝日付きカレンダー(内閣府API)
cal
コマンドはlinuxやmacOSのターミナルでカレンダーを表示できるシェルです。ターミナルで高速表示できるカレンダーは地味に便利で重宝しています。
項目 | コマンド |
---|---|
今月のカレンダーを表示 | cal |
指定した月のカレンダーを表示 | cal 3 2024 |
年間カレンダーを一覧で表示 | cal 2024 |
先月、当月、翌月のカレンダーを表示 | cal -3 |
とくに先月・当月・翌月を表示する cal -3
が便利なのですが、祝日も表示できないかと調べたところ、以下の方法がありました。
cal -3; curl -s https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | iconv -f SHIFT-JIS -t UTF-8 | grep -E "`date -v-1m '+%Y/%-m/'`|`date '+%Y/%-m/'`|`date -v+1m '+%Y/%-m/'`"
実行結果:
$ cal3
8月 2025 9月 2025 10月 2025
日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土
1 2 1 2 3 4 5 6 1 2 3 4
3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11
10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18
17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25
24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31
31
2025/8/11,山の日
2025/9/15,敬老の日
2025/9/23,秋分の日
2025/10/13,スポーツの日
内閣府が発行している祝日のcsvデータをcurl
でフェッチし、iconv
でshift-jisからutf-8へ文字エンコード処理を行います。そして、csvデータの中から、cal -3
のカレンダー表示に合わせて先月、当月、翌月の祝日データをgrep
でフィルタリングして表示させてます。
.zshrc
に cal3
などで登録しておくと便利です。
alias cal3="cal -3; curl -s https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | iconv -f SHIFT-JIS -t UTF-8 | grep -E \"\$(date -v-1m '+%Y/%-m/')|\$(date '+%Y/%-m/')|\$(date -v+1m '+%Y/%-m/')\""
参考: https://iwb.jp/terminal-cal-command-calendar-holiday-list/
天気情報取得(気象庁API)
気象庁のデータAPIが公開されているので cal3
同様にそちらを利用して天気、気温、風速などの情報を表示させます。
curl https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json | jq
参考:
取得した json
を整形して出力させる処理を、
wx
としてコマンド化し、 .zshrc
に登録させました。
alias wx="curl -s 'https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json' \
| jq -r '
.[0].timeSeries[0] as \$ts0 |
.[0].timeSeries[1] as \$ts1 |
.[0].timeSeries[2] as \$ts2 |
\"地域: \(\$ts0.areas[0].area.name)\n天気: \(\$ts0.areas[0].weathers[0])\n風: \(\$ts0.areas[0].winds[0])\n波: \(\$ts0.areas[0].waves[0] // \"-\")\n降水確率: \(\$ts1.areas[0].pops[0] // \"-\")/\(\$ts1.areas[0].pops[1] // \"-\")/\(\$ts1.areas[0].pops[2] // \"-\")/\(\$ts1.areas[0].pops[3] // \"-\")\n最高気温: \(\$ts2.areas[0].temps[0] // \"-\")℃\n最低気温: \(\$ts2.areas[0].temps[2] // \"-\")℃\"
'"
実行結果:
$ wx
域: 東京地方
天気: くもり 時々 雨 所により 夕方 雷を伴い 非常に 激しく 降る
風: 南西の風 後 北東の風 23区西部 では 南西の風 やや強く
波: 1メートル 後 0.5メートル
降水確率: 50/60/60/60
最高気温: 32℃
最低気温: 24℃
https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=130000
残念ながらmacOSのターミナルからGP取得する方法が見つからなかったため、位置情報は決め打ちにしました。
地震情報(気象庁API)
地震などの災害時は、サイトアクセス過多で接続できないことがよくありますが、次のようにjsonファイルだけならアクセスできるかもしれませんね。
# 地震情報(直近1週間分)
quake() {
curl -s "https://www.jma.go.jp/bosai/quake/data/list.json" \
| jq -r '
["日時","震源地","M","最大震度"],
(
.[]
| select((.anm // "") != "")
| (.at | sub("\\+09:00$"; "") | strptime("%Y-%m-%dT%H:%M:%S")) as $ts
| select(($ts | mktime) >= (now - 7*24*60*60))
| [
($ts | strftime("%Y-%m-%d %H:%M")),
.anm,
(.mag // "-"),
(.maxi // "-")
]
)
| @tsv
' \
| column -t -s $'\t'
}
使い方:
$ quake
日時 震源地 M 最大震度
2025-09-13 12:19 秋田県内陸北部 2.6 1
2025-09-13 11:38 カムチャツカ半島付近 7.5
2025-09-13 05:03 伊豆大島近海 2.4 1
2025-09-13 03:09 薩摩半島西方沖 2.1 1
2025-09-13 00:57 北海道東方沖 4.7 2
2025-09-13 00:48 宮城県沖 3.7 1
2025-09-12 19:57 山梨県東部・富士五湖 2.8 1
私のmacOS環境の dotfiles
をGitHubで公開してますので何かの参考に
シェルからChatGPTを呼び出す(OpenAI API)
以下の方法はOpenAI
APIキーが必要になります。事前にクレジットの購入が必要です。
https://platform.openai.com/
次のように、ターミナルからChatGPTに直接質問するシェルスクリプトを作ってみました。
#!/bin/bash
API_KEY="sk-..." # OpenAIのAPIキー
ENDPOINT="https://api.openai.com/v1/chat/completions"
MODEL="gpt-4o"
# 入力を標準入力から取得
INPUT=$(cat)
# 入力をJSONエスケープ(1行の安全な文字列に)
ESCAPED_INPUT=$(printf '%s' "$INPUT" | jq -Rs .)
# JSONリクエストボディを組み立て
JSON=$(cat <<EOF
{
"model": "$MODEL",
"messages": [
{
"role": "system",
"content": "あなたは日本語で答えるAIアシスタントです。"
},
{
"role": "user",
"content": $ESCAPED_INPUT
}
],
"temperature": 0.7
}
EOF
)
# APIリクエスト送信
RESPONSE=$(curl -s "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$JSON")
# エラーチェック
if echo "$RESPONSE" | jq -e '.error' > /dev/null; then
echo "エラー: $(echo "$RESPONSE" | jq -r '.error.message')" >&2
exit 1
fi
# 出力
echo "$RESPONSE" | jq -r '.choices[0].message.content'
使い方は次のとおり:
# 例1
echo "ChatGPTとは何ですか?" | ./chatgpt.sh
# 例2
cat q.txt | ./chatgpt.sh
2025年3月時点の OpenAI API モデル料金
モデル | 入力(Prompt) | 出力(Response) |
---|---|---|
gpt-3.5-turbo | 0.0005ドル / 1,000トークン | 0.0015ドル / 1,000トークン |
gpt-4-turbo | 0.01ドル / 1,000トークン | 0.03ドル / 1,000トークン |
gpt-4o(おすすめ) | 0.005ドル / 1,000トークン | 0.015ドル / 1,000トークン |
- 1トークン = 英語で約4文字、日本語だと1〜2文字程度
- たとえば「こんにちは、調子はどう?」→ 約10トークン前後
- 質問+回答をあわせて1,000〜2,000トークンが平均的です
- gpt-4o を使った場合、10ドル ÷ 0.02ドル = 約 500回 質問可能です
GhostScript でPDFの圧縮
ここからは API ではありませんが、便利なライブラリのエイリアス化を紹介します。
macOSでPDFをコマンドラインで圧縮する方法で、自炊などで電子書籍化したPDFデータの容量を圧縮したい時におすすめです。
GhostScript
というソフトウェアを使ってPDFを圧縮します。macOSの場合は
brew
を使ってインストールできます。
パッケージ | バージョン | インストールコマンド |
---|---|---|
gs | 10.01.2 | brew install ghostscript |
次のように圧縮したいPDF in.pdf
を次のコマンドで圧縮して
out.pdf
として書き出すことができます。
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf in.pdf
試してみたところ、138MBあったPDFが76MBへ削減できました!およそ50%の圧縮です!
PDFSETTINGS
オプションを変更することで圧縮率を高める方法もありますが、電子書籍だと文字が読めない状態になってしまいましたのでここでは紹介しません。
ワンライナー化してエイリアスに登録しました。
# PDF圧縮
alias pdfmin='f(){ input="$1"; output="${input%.*}_min.pdf"; gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$output" "$input" && echo "$output"; }; f'
モノによっては大して圧縮されなかったり、圧縮自体がエラーになってうまく書き出せなかったりしますのでご注意ください。圧縮エラーになるファイルが結構ありました。