1

我正在编写一个使用 xmllint 解析 rss 的小脚本。

现在我使用以下命令获取标题列表:

ITEMS=`echo "cat //title" | xmllint --shell rss.xml `
echo $ITEMS > tmpfile

但它返回:

<title>xxx</title> ------- <title>yyy :)</title> ------- <title>zzzzzz</title>

没有换行符或空格。现在我只对标题标签的文本内容感兴趣,如果可能的话,我想使用 for/while 循环浏览标题,例如:

for  val in $ITEMS 
do
       echo $val
done

怎么做?提前致谢

4

3 回答 3

5

在某些时候,我有相同类型的要求来解析 bash 中的 xml。我最终使用了 xmlstarlet http://xmlstar.sourceforge.net/,您可能可以安装它。

如果没有,类似的东西会删除周围的标签:

echo "cat  //title/text()" | xmllint --shell  rss.xml

然后你需要在管道后清理输出,一个基本的解决方案是:

echo "cat  //title/text()" | xmllint --shell  rss.xml  | egrep '^\w'

希望这可以帮助

于 2012-05-11T14:14:19.657 回答
2

$ITEMS要回答您的第一个问题, with的未引用用法echo是消除您的换行符。尝试

ITEMS=`echo "cat //title" | xmllint --shell rss.xml `
echo "$ITEMS" > tmpfile
#----^------^--- dbl-quotes only

一般来说,使用for循环最好留给不会产生意外空格或其他不可打印字符的项目。(非字母数字),例如for i in {1..10} ; do echo $i; done

而且你真的不需要变量或临时文件,试试

  echo "cat //title" | xmllint --shell rss.xml |
  while read line ; do
      echo "$line"
  done

根据您的 rrs 提要中的内容,您还可以从更改读取 cmd 使用的默认 IFS(内部字段分隔符)中受益,尝试

while IFS= read line ....
# or 
while IFS="\n" read line
# or
while IFS="\r\n" read line

我不确定你想通过echo "cat //title" |进入 xmllint 来实现什么,所以我保持原样。这是对 xmllint 的指令吗?还是通过创建文档标题?(现在没有 xmllint 可以体验)。

此外,您可能想查看使用 awk 阅读 rss 提要,但它的级别相当低。

我希望这有帮助。

于 2012-05-11T13:42:38.527 回答
1

除了Philippe 的回答,如果你想直接从类似的命令cURL获取 xml 输出,你可以使用另一个文件描述符来管道它。

事实上,STDIN 已经被xmllinttshell 输入所占用。下面是一个工作示例(只需记住将 URL 参数替换为您的)。

# Create a temporary file and use it as third fd
exec 3<> $(tempfile) &&
# cURL the RSS URL and redirect STDOUT to the 3rd fd
curl https://your-url/to/some/rss.xml >&3 &&
# Then read  fd 3 with xmllint
xmllint --format --shell /dev/fd/3 <<< 'cat //title/text()' | egrep '^\w' &&
# Close the temporary file (remember global warming issues)
exec 3>&-
于 2020-06-27T16:20:36.427 回答