2017-09-16 107 views
1

這是一個相當煩人,但相當簡單的任務。根據這一guide,我寫了這個:Unescape通過XMLStarlet的&符(&) - Bugging &

#!/bin/bash 

content=$(wget "https://example.com/" -O -) 
ampersand=$(echo '\&') 

xmllint --html --xpath '//*[@id="table"]/tbody' - <<<"$content" 2>/dev/null | 
    xmlstarlet sel -t \ 
     -m "/tbody/tr/td" \ 
      -o "https://example.com" \ 
      -v "a//@href" \ 
      -o "/?A=1" \ 
      -o "$ampersand" \ 
      -o "B=2" -n \ 

我成功地提取從表中的每個環節,一切都被正確地連接在一起,然而,而不是再現符號&我收到這在年底每一個環節:

https://example.com/hello-world/?A=1\&amp;B=2 

但實際上,我一直在尋找類似:

https://example.com/hello-world/?A=1&B=2 

這個想法是使用反斜槓\&來避開字符,以便它被忽略。最初,我嘗試將其直接放入-o "\&" \而不是-o "$ampersand" \,並在此情況下刪除ampersand=$(echo '\&')。還是一樣的結果。

本質上,通過去除反斜槓它仍然輸出:

https://example.com/hello-world/?A=1&amp;B=2 

只有所述&amp;後面的\被去除。

爲什麼?

我確定這是缺少的基本東西。

+0

要提高你的答案的質量,您應該包括一些樣本輸入與期望的輸出一起,所以我們可以測試可能的解決方案。 –

+0

你是對的。我會按照你的建議!歡呼@TomFenech –

回答

1

對不起,我無法重現您的結果,但爲什麼不進行換人?只需通過篩選結果

sed 's/\\&amp;/\&/g' 

將其添加到您的管道。它應該取代所有的& amp;到&。

+0

嗨@vollitwr我認爲你應該在最後刪除'**',否則我認爲在這裏管理這個sed的最好。 –

+0

對不起,它是固定的。它仍然是Stackoverflow格式。 – vollitwr

1

正如您已經看到的,反斜槓轉義不是這裏的解決方案。我能想到的兩個可能的選擇:

提取的HREFs(也許並不需要使用xmllintxmlstarlet做到這一點),那麼只需使用標準文本處理工具,如sed添加啓動和結尾:

sed 's,^,https://example.com/,; s,$,/?A=1\&B=2,' 

另外,管的是什麼你現在得xmlstarlet unesc輸出,這將改變&amp;&

+0

嗨@TomFenech管道'xmlstarlet unesc'爲我工作。謝謝! –

1

&amp;是在XML文檔中打印&的正確方法,但既然您只是想要一個普通的URL,則您的輸出不應該是XML。因此,您需要切換到文本模式,方法是將--text-T傳遞給sel命令。

您的示例輸入不起作用,因爲example.com沒有任何table元素,但此處是構建p元素鏈接的工作示例。

content=$(wget 'https://example.com/' -O -) 
xmlstarlet fo --html <<<"$content" | 
    xmlstarlet sel -T -t \ 
     -m '//p[a]' \ 
      --if 'not(starts-with(a//@href,"http"))' \ 
       -o 'https://example.com/' \ 
      --break \ 
      -v 'a//@href' \ 
      -o '/?A=1' \ 
      -o '&' \ 
      -o 'B=2' -n 

輸出是

http://www.iana.org/domains/example/?A=1&B=2 
+0

嗨@npostavs,它很好地簡化了我的腳本。在我的情況下'--if'是多餘的,因爲所有要提取的鏈接都缺少基礎url。此外,它的效果很好。乾杯! –