BBC NewsのRSSフィードを取得するスクリプトを改修しました。
改修した点
-mフラグの処理:- 引数に
-mが指定された場合、インタラクティブモード(対話式)の関数を呼び出します。
- 引数に
- セクションの番号選択:
- 統合された全セクションを1から順にナンバリングして表示し、ユーザーが数字で選べるようにしました。
- 件数の入力:
- デフォルト値を提示しつつ、エンターを押すだけでデフォルト値(3件)が適用される親切設計にしています。
改修版スクリプト
#!/bin/bash
# デフォルト値の設定
default_section="world"
default_count=3
# メインセクションのリスト
main_sections=("world" "uk" "business" "politics" "health" "education" "science_and_environment" "technology" "entertainment_and_arts")
# グローバルセクションのリスト
global_sections=("africa" "asia" "europe" "latin_america" "middle_east" "us_and_canada")
# 全セクションのリストを統合
all_sections=("${main_sections[@]}" "${global_sections[@]}")
# --- [新規] 対話式メニュー関数 ---
interactive_menu() {
echo "=== BBC News RSS セクション選択 ==="
# セクション一覧を番号付きで表示
for i in "${!all_sections[@]}"; do
printf "%2d) %s\n" "$((i+1))" "${all_sections[$i]}"
done
# セクションの入力受付
while true; do
read -p "セクションの番号を選択してください (1-${#all_sections[@]}): " sec_num
if [[ "$sec_num" =~ ^[0-9]+$ ]] && [ "$sec_num" -ge 1 ] && [ "$sec_num" -le "${#all_sections[@]}" ]; then
section="${all_sections[$((sec_num-1))]}"
break
else
echo "無効な入力です。正しい番号を入力してください。"
fi
done
# 件数の入力受付
read -p "表示する件数を入力してください (デフォルト: ${default_count}): " input_count
if [[ "$input_count" =~ ^[0-9]+$ ]] && [ "$input_count" -gt 0 ]; then
count=$input_count
else
count=$default_count
fi
echo "--------------------------------------------------"
}
# --- 引数の処理 ---
if [[ "$1" == "-m" ]]; then
# 対話モードの起動
interactive_menu
elif [[ "$1" =~ ^[0-9]+$ ]]; then
section=$default_section
count=$1
else
section=${1:-$default_section} # 引数1が指定されていない場合はデフォルト値を使用
count=${2:-$default_count} # 引数2が指定されていない場合はデフォルト値を使用
fi
# 引数の短縮形を対応する正式名に変換 (通常モード用)
case "$section" in
"usa" | "n-usa") section="us_and_canada" ;;
"me") section="middle_east" ;;
"latam" | "la") section="latin_america" ;;
"eu") section="europe" ;;
"science") section="science_and_environment" ;;
"entertainment") section="entertainment_and_arts" ;;
*) section=$section ;; # その他はそのまま
esac
# セクションの検証
if [[ ! " ${all_sections[@]} " =~ " ${section} " ]]; then
echo "Error: Invalid section '${section}'. Valid sections are: ${all_sections[*]}"
exit 1
fi
# URLの構築
if [[ " ${main_sections[@]} " =~ " ${section} " ]]; then
url="https://feeds.bbci.co.uk/news/${section}/rss.xml"
else
url="https://feeds.bbci.co.uk/news/world/${section}/rss.xml"
fi
# 最初に一度だけRSSフィードをダウンロードし、変数に格納する
xml_content=$(curl -s "$url")
# コンテンツが取得できなかった場合はエラー終了
if [ -z "$xml_content" ]; then
echo "Error: No headlines found for section '${section}'. Please check the section name or try again later."
exit 1
fi
# フィードの最終更新日時を取得し、フォーマットする
feed_date_raw=$(echo "$xml_content" | xmllint --xpath "string(//channel/lastBuildDate)" - 2>/dev/null)
if [ -n "$feed_date_raw" ]; then
# JSTに変換して表示フォーマットを整える
feed_date_formatted=$(date -d "$feed_date_raw" '+%Y/%m/%d %H:%M:%S %Z')
fi
# 見出しを取得
headlines=$(echo "$xml_content" | xmllint --xpath "//item/title/text()" - 2>/dev/null | sed -e 's/<!\[CDATA\[//g' -e 's/\]\]>//g' | head -n "$count")
# 見出しの表示
echo "BBC News - ${section} section (${count} headlines)"
# 取得した日付を表示
if [ -n "$feed_date_formatted" ]; then
echo "As of: ${feed_date_formatted}"
fi
echo "--------------------------------------------------" #区切り線
echo "$headlines"
使い方
- 通常モード(従来通り)
引数をそのまま渡せば、セクションごとに件数を表示してくれます。
./bbc_headline.sh business 5
- 対話式メニューモード(新機能)
-m を付けて実行します。
./bbc_headline.sh -m
実行イメージ:
=== BBC News RSS セクション選択 ==
1) world
2) uk
...
15) us_and_canada
セクションの番号を選択してください (1-15): 3
表示する件数を入力してください (デフォルト: 3): 5
--------------------------------------------------
BBC News - business section (5 headlines)
...
graph TD
A("スクリプト開始") --> B{"引数の判定"}
%% 引数の分岐
B -->|"-m"| C["対話式メニュー関数 interactive_menu"]
B -->|"数字"| D["セクション: デフォルト<br>件数: 引数1の数字"]
B -->|"その他"| E["セクション: 引数1<br>件数: 引数2"]
%% 対話モードの詳細
subgraph "対話モードの内部処理"
C --> C1["セクション一覧を番号付きで表示"]
C1 --> C2["ユーザーが番号を入力"]
C2 --> C3{"有効な番号か?"}
C3 -->|"No"| C2
C3 -->|"Yes"| C4["セクション名を確定"]
C4 --> C5["ユーザーが表示件数を入力"]
C5 --> C6{"数字が入力されたか?"}
C6 -->|"Yes"| C7["入力された件数を採用"]
C6 -->|"No"| C8["デフォルトの3件を採用"]
end
%% 合流後の共通処理
C7 --> F["短縮名の変換ケース文"]
C8 --> F
D --> F
E --> F
F --> G{"有効なセクション名か?"}
G -->|"No"| H("エラーを表示して終了")
G -->|"Yes"| I{"メインかグローバルか?"}
%% URL構築
I -->|"メイン"| J["URL: news/セクション/rss.xml"]
I -->|"グローバル"| K["URL: news/world/セクション/rss.xml"]
%% 取得と出力
J --> L["curl で RSS XML をダウンロード"]
K --> L
L --> M{"データが空でないか?"}
M -->|"No"| N("エラーを表示して終了")
M -->|"Yes"| O["xmllint で最終更新日時を取得・JST変換"]
O --> P["xmllint と head で見出しを抽出"]
P --> Q["結果を画面に出力"]
Q --> R("スクリプト終了")
%% スタイルの調整
style C fill:#f9f,stroke:#333,stroke-width:2px
style C1 fill:#fff2cc,stroke:#d6b656
style C2 fill:#fff2cc,stroke:#d6b656
style C5 fill:#fff2cc,stroke:#d6b656
このスクリプトは役に立つのか?
私が便利だと思ったから乗せています。実際、/etc/update-motdに仕込むことで、「今はこういう出来事が起こっている」をリアルタイムで知ることができるからです。
コメントを残す