如何使用read解析rss xml中的额外属性

时间:2019-08-26 19:25:24

标签: xml bash rss

我想从Jackett解析数据,最初我尝试使用flexget,但是我需要提取各种插件中不存在的数据,因此我从这个小脚本开始,以尝试解析那些额外的数据。 我的rss是这样的

<?xml version="1.0" encoding="UTF-8"?>
<rss version="1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:torznab="http://torznab.com/schemas/2015/feed">
  <channel>
    <atom:link href="http://jackett:9117/" rel="self" type="application/rss+xml" />
    <title>site description</title>
    <description>A general italian tracker</description>
    <link>https://site.some/</link>
    <language>en-us</language>
    <category>search</category>
    <image>
      <url>http://jackett:9117/logos/site.png</url>
      <title>site description</title>
      <link>https://site.some/</link>
      <description>site description</description>
    </image>
    <item>
      <title>Pinnacle Studio Ultimate v23 0 1 177 64 Bit Content Pack</title>
      <guid>https://site.some/index.php?page=torrent-details&amp;id=id</guid>
      <jackettindexer id="site">site description</jackettindexer>
      <comments>https://site.some/index.php?page=torrent-details&amp;id=id</comments>
      <pubDate>Mon, 26 Aug 2019 18:47:48 +0200</pubDate>
      <size>4778150912</size>
      <grabs>4</grabs>
      <description />
      <link>http://jackett:9117/dl/site/?jackett_apikey=apikey&amp;path=Q2ZESjhIOTlRbnNBaTlsTXBueG41dVNtYWFqVjlsbTFockNDVXRieE5OYXRQYTdnclc4Zmc2dGJVNlFiQ01SVW9Wbm9yblJaZnhWXy0wSnVocHRISGxkYmNQLVQ5aWh6S1RORWtqMmwzMTlvTUFNZHlrV1c2czBlbjhNczlFa3VuQ1RxVjRsTkM0UGxRc2RUYzllR0tJaTBVMFFtMWc0UHIybnl0eFVkbGZqcUxuR1BPRDN0MGYwWUNNcVZ5d3NWazgta0Z0SkdrUUZIYnpZZWpUOTA1V2F5b1JGMEpTWlZVSzN0bVkzYzFMU09BLTlBck54bERpRU0yZ3lNTzkwcDU3amhNWE1MOXZmWFhLSEJaa1gwWEpWMHFYUFRfMFMtSlJQX05oalRMNmtpTlc4S0NueDF6c1VZazZfTkg0bE1IZFF5cEE&amp;file=Pinnacle+Studio+Ultimate+v23+0+1+177+64+Bit+Content+Pack</link>
      <category>4010</category>
      <category>100007</category>
      <enclosure url="http://jackett:9117/dl/site/?jackett_apikey=apikey&amp;path=Q2ZESjhIOTlRbnNBaTlsTXBueG41dVNtYWFqVjlsbTFockNDVXRieE5OYXRQYTdnclc4Zmc2dGJVNlFiQ01SVW9Wbm9yblJaZnhWXy0wSnVocHRISGxkYmNQLVQ5aWh6S1RORWtqMmwzMTlvTUFNZHlrV1c2czBlbjhNczlFa3VuQ1RxVjRsTkM0UGxRc2RUYzllR0tJaTBVMFFtMWc0UHIybnl0eFVkbGZqcUxuR1BPRDN0MGYwWUNNcVZ5d3NWazgta0Z0SkdrUUZIYnpZZWpUOTA1V2F5b1JGMEpTWlZVSzN0bVkzYzFMU09BLTlBck54bERpRU0yZ3lNTzkwcDU3amhNWE1MOXZmWFhLSEJaa1gwWEpWMHFYUFRfMFMtSlJQX05oalRMNmtpTlc4S0NueDF6c1VZazZfTkg0bE1IZFF5cEE&amp;file=Pinnacle+Studio+Ultimate+v23+0+1+177+64+Bit+Content+Pack" length="4778150912" type="application/x-bittorrent" />
      <torznab:attr name="category" value="4010" />
      <torznab:attr name="category" value="100007" />
      <torznab:attr name="seeders" value="4" />
      <torznab:attr name="peers" value="6" />
      <torznab:attr name="minimumratio" value="1" />
      <torznab:attr name="minimumseedtime" value="172800" />
      <torznab:attr name="downloadvolumefactor" value="1" />
      <torznab:attr name="uploadvolumefactor" value="1" />
    </item>
  </channel>
</rss>

所以最初,我的第一个想法是解析每个部分以提取信息,所以我想到了这一点

#!/bin/bash

xmlgetnext () {
   local IFS='>'
   read -d '<' TAG VALUE
}

# /data/Varie/Scripts/mmm


cat /data/Varie/Scripts/mmm | while xmlgetnext ; do
   case $TAG in
      'item')
         title=''
         link=''
         description=''
         downloadvolumefactor=''
         ;;
      'title')
         title="$VALUE"
         ;;
      'link')
         link="$VALUE"
         ;;
      'downloadvolumefactor')
         downloadvolumefactor="$VALUE"
         ;;
      '/item')
         cat<<EOF
------------------------------
Title: $title
Link: $link
Custom value: $downloadvolumefactor
------------------------------
EOF
         ;;
      esac
done

因此阅读从第一个<开始,直到下一个<阅读,然后设置 TAG VALUE

这对我来说还可以,问题是我找不到提取downloadvolumefactor的方法,因为该值的格式不像标准格式。

我的第一个想法是在解析rss之前对其进行修改,因此也许我可以使用替换的正则表达式进行转换

<torznab:attr name="uploadvolumefactor" value="1" />

进入

<downloadvolumefactor>1</downloadvolumefactor>

您有更好的主意吗?

2 个答案:

答案 0 :(得分:1)

这是一个简单的awk(标准Linux gnu awk或gawk)脚本,解决了将输入文件扫描为纯文本的问题。

script.awk

match($0,"<title>[^<]*", arr) {title=substr(arr[0],8)}   # read title line
match($0,"<link>[^<]*", arr) {link=substr(arr[0],7)}     # read link line
match($0,/uploadvolumefactor" value="[^"]/, arr) {valueFactor=substr(arr[0],28)} # read valueFactor line
/<\/item>/ { # ouput values on item element termination
    print "------------------------------";
    print "Title: "title;
    print "Link: "link;
    print "Custom value: "valueFactor;
    print "------------------------------";
}

运行:

awk -f script.awk input.xml

在问题中提供了input.xml

输出:

------------------------------
Title: Pinnacle Studio Ultimate v23 0 1 177 64 Bit Content Pack
Link: http://jackett:9117/dl/site/?jackett_apikey=apikey&amp;path=Q2ZESjhIOTlRbnNBaTlsTXBueG41dVNtYWFqVjlsbTFockNDVXRieE5OYXRQYTdnclc4Zmc2dGJVNlFiQ01SVW9Wbm9yblJaZnhWXy0wSnVocHRISGxkYmNQLVQ5aWh6S1RORWtqMmwzMTlvTUFNZHlrV1c2czBlbjhNczlFa3VuQ1RxVjRsTkM0UGxRc2RUYzllR0tJaTBVMFFtMWc0UHIybnl0eFVkbGZqcUxuR1BPRDN0MGYwWUNNcVZ5d3NWazgta0Z0SkdrUUZIYnpZZWpUOTA1V2F5b1JGMEpTWlZVSzN0bVkzYzFMU09BLTlBck54bERpRU0yZ3lNTzkwcDU3amhNWE1MOXZmWFhLSEJaa1gwWEpWMHFYUFRfMFMtSlJQX05oalRMNmtpTlc4S0NueDF6c1VZazZfTkg0bE1IZFF5cEE&amp;file=Pinnacle+Studio+Ultimate+v23+0+1+177+64+Bit+Content+Pack
Custom value: 1
------------------------------

答案 1 :(得分:0)

使用xml感知工具。

xmllint --xpath 'string(//*[name()="torznab:attr" and @name="downloadvolumefactor"]/@value)' /data/Varie/Scripts/mmm

会返回:

1

请勿使用正则表达式解析xml文件。

如果必须,何时,使用awksedgrep过滤{{1 }}和类似的内容:

cut

重击虽然读取循环非常慢,但最好使用其他工具。如果文件格式稳定并且您无法使用sed -nr '/.*<torznab:attr name="uploadvolumefactor" value="([^"]*).*/s//\1/p' /data/Varie/Scripts/mmm 或其他xml感知工具,则可以使用xmllint进行准备-阅读一行,从中提取信息,添加保留的空间,继续阅读并进行分析,直到遇到sed。但是使用xml感知工具将是安全的,并且不易出错。