2017-09-16 45 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。此外,它的效果很好。干杯! –