You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:编写Bash脚本下载RSS Feed并保存为独立HTML文件失败,求排查错误

修复Bash RSS下载脚本的问题

原脚本的核心错误

  • 正则表达式转义错误:代码里的(?&lt;=是HTML转义后的<,实际Bash环境中需要用(?<=),否则grep的Perl正则引擎无法识别,直接导致匹配失败。
  • RSS结构解析逻辑错误:HN的RSS中,每个条目是<item>节点,<title>和<description>是同级节点,并非<description>包含<title>,原脚本的提取逻辑完全颠倒。
  • 未处理文件名特殊字符:标题中包含的空格、/、?等字符会导致创建文件时报错,必须清理或转义。
  • read命令行为问题:默认while read会截断换行、压缩空格,需要用IFS= read -r来保留内容完整性。
  • 冗余管道处理:多次重复用sed和grep处理标签,逻辑混乱且效率低下。

推荐修正方案(使用XML专用解析工具)

用xmlstarlet(需提前安装,如apt install xmlstarlet或brew install xmlstarlet)解析RSS,这是处理XML/RSS最可靠的方式:

#!/bin/bash
RSS_URL="https://news.ycombinator.com/rss"
OUTPUT_DIR="hn_articles"

# 创建输出目录,避免报错
mkdir -p "$OUTPUT_DIR"

# 解析RSS,提取每个item的标题和描述,用分隔符分隔
xmlstarlet sel -t -m "/rss/channel/item" -v "title" -o "|||" -v "description" -n "$RSS_URL" | while IFS="|||" read -r title description; do
  # 清理标题中的非法文件名字符,替换为下划线
  safe_title=$(echo "$title" | sed 's/[\/:*?"<>|]/_/g' | tr -s '_')
  filename="${OUTPUT_DIR}/${safe_title}.html"
  
  # 仅当文件不存在时创建
  if [ ! -f "$filename" ]; then
    # 生成标准HTML结构
    echo "<!DOCTYPE html><html><head><title>$title</title></head><body>$description</body></html>" > "$filename"
    echo "Created: $filename"
  fi
done

无XML工具的替代方案(基于grep/sed)

如果无法安装xmlstarlet,可以用以下改进版脚本(依赖RSS格式规整,标签不跨过多换行):

#!/bin/bash
RSS_URL="https://news.ycombinator.com/rss"
OUTPUT_DIR="hn_articles"
TMP_FILE="/tmp/hn_rss.tmp"

mkdir -p "$OUTPUT_DIR"

# 静默下载RSS到临时文件
curl -L -s "$RSS_URL" > "$TMP_FILE"

# 遍历每个item的标题和描述
grep -A 2 "<item>" "$TMP_FILE" | while IFS= read -r line; do
  if [[ "$line" =~ "<title>" ]]; then
    # 提取标题内容
    title=$(echo "$line" | sed 's/.*<title>//;s/<\/title>.*//')
  elif [[ "$line" =~ "<description>" ]]; then
    # 提取描述内容
    description=$(echo "$line" | sed 's/.*<description>//;s/<\/description>.*//')
    # 处理合法文件名
    safe_title=$(echo "$title" | sed 's/[\/:*?"<>|]/_/g' | tr -s '_')
    filename="${OUTPUT_DIR}/${safe_title}.html"
    if [ ! -f "$filename" ]; then
      echo "<!DOCTYPE html><html><head><title>$title</title></head><body>$description</body></html>" > "$filename"
      echo "Created: $filename"
    fi
    # 重置变量,避免污染下一个条目
    title=""
    description=""
  fi
done

# 清理临时文件
rm "$TMP_FILE"

内容的提问来源于stack exchange,提问作者zeddie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:50:23