我想寫一個腳本:
- 將一些 RSS-Feed URL 作為輸入
- 下載提要
- 刪除標籤與某些正規表示式不符的所有
<item> ...</item>
符合項目。title
下面的例子應該要說明這一點。假設我們有一個包含這三項的 RSS 來源:
- Foo 專案 - 讓我們開始吧!
- 完全是別的東西
- Project Foo 的另一個更新
我只想保留那些標題中包含「Project Foo」的項目。
輸入檔案範例:
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>My glorious newsfeed</title>
<description>...</description>
<link>...</link>
<language>...</language>
<pubDate>...</pubDate>
<item>
<title>Project Foo - Let's get started!</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>
<item>
<title>Something else entirely</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>
<item>
<title>Another update on Project Foo</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>
</channel>
</rss>
輸出檔案範例:
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>My glorious newsfeed</title>
<description>...</description>
<link>...</link>
<language>...</language>
<pubDate>...</pubDate>
<item>
<title>Project Foo - Let's get started!</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>
<item>
<title>Another update on Project Foo</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>
</channel>
</rss>
如果可能的話,我想遠離類似的工具python
並使用命令列工具來完成此操作。但我是使用等的大新手sed
,需要一些幫助:)
這是我到目前為止所擁有的:
cat sample-feed.xml \
| tr -d '\n' \
| sed $'s/\<item\>/\\\n\<item\>/g;s/\<\/channel\><\/rss\>/\\\n\<\/channel\><\/rss\>/g' \
| sed '/^\<item\>/ d'
首先,我刪除所有換行符。然後,我添加換行符以將每個換行符<item>...</item>
放在自己的行上。到目前為止,最後的命令刪除所有以 開頭的行<item>
。為了
結果是一個有效的 rss-feed,沒有任何項目:
<?xml version="1.0" encoding="iso-8859-1"?><rss version="2.0"><channel><title>My glorious newsfeed</title><description>...</description><link>...</link><language>...</language><pubDate>...</pubDate>
</channel></rss>
為了使用 URL 而不是本地文件進行此操作,我只需將其替換cat sample-feed.xml
為curl -s <some url>
.
但仍缺少的是對命令的修改,sed '/^\<item\>/ d'
該命令僅刪除以「Project Foo」開頭<item>
但不包含「Project Foo」的行。
所以,如果你能幫我弄清楚最後一行我該說什麼,我會非常高興。另一方面,我確信有一種更優雅的方法可以做到這一點。據我所知,sed
它非常強大,應該可以用一個sed
命令來完成此操作。
期待您的回覆:-)
答案1
正如評論中所建議的,我嘗試使用它xmlstarlet
來解決這個問題並且效果很好。這是我的腳本
xml ed -d '//item[not(contains(title,"Project Foo"))]' < sample_rss.xml
我們假設提要內容位於文件中sample_rss.xml
。該內容將被輸入到 中xml ed -d
,從而刪除與給定 XPath 表達式相符的任何註釋。 XPath 表達式會尋找任何<item>
不具有<title>
包含文字的節點的節點"Project Foo"
。
這看起來效果很好,我對執行時間也很滿意:
real 0m0.003s
user 0m0.001s
sys 0m0.002s
當心命名空間
如果您想要使用適當的 rss 或 Atom 提要來實現此功能,您可能會注意到其中feed
包含 XML 命名空間 ( xmlns
) 屬性,就像 YouTube 中的範例一樣:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
...
</feed>
那麼,上面的腳本將不再起作用!修復它讓我相當頭疼,但以下是讓它發揮作用的方法:
xml ed -d '//_:entry[not(contains(_:title,"Project Foo"))]' < youtube_rss.xml
有關此命名空間問題的更多信息,請參見此處:http://xmlstar.sourceforge.net/doc/UG/ch05.html