2

好吧,这很容易,但我无法弄清楚。

基本上我想<a href="[^<>]*">[^<>]*</a>从一个大html文件中提取所有链接()。

我试图用 来做到这一点sed,但我得到了各种各样的结果,只是不是我想要的。我知道我的正则表达式是正确的,因为我可以替换文件中的所有链接:

sed 's_<a href="[^<>]*">[^<>]*</a>_TEST_g'

如果我在类似的东西上运行它

<div><a href="http://wwww.google.com">A google link</a></div>
<div><a href="http://wwww.google.com">A google link</a></div>

我明白了

<div>TEST</div>
<div>TEST</div>

我怎样才能摆脱其他一切而只打印匹配项?我更喜欢的最终结果是:

<a href="http://wwww.google.com">A google link</a>
<a href="http://wwww.google.com">A google link</a>

PS。我知道我的正则表达式不是最灵活的,但对于我的意图来说已经足够了。

4

4 回答 4

3

匹配整行,将有趣的部分放在一个组中,替换为组的内容。使用-n选项来抑制不匹配的行,并添加p修饰符以打印s命令的结果。

sed -n -e 's!^.*\(<[Aa] [^<>]*>.*</[Aa]>\).*$!\1!p'

请注意,如果该行有多个链接,则仅打印最后一个链接。您可以对此进行改进,但它超越了简单的 sed 用法。最简单的方法是使用两个步骤:首先在任意两个链接之前插入换行符,然后提取链接。

sed -n -e 's!</a>!&\n!p' | sed -n -e 's!^.*\(<[Aa] [^<>]*>.*</[Aa]>\).*$!\1!p'

这仍然不能处理 HTML 注释、<pre>分布在多行的链接等。解析 HTML 时,请使用 HTML 解析器

于 2012-08-25T23:49:27.047 回答
1

假设每行只有一个超链接,则以下可能有效...

  sed -e 's_.*<a href=_<a href=_' -e 's_>.*_>ed <<'EOF'
 -e 's_.*<a href=_<a href=_' -e 's_>.*_>_'
于 2012-08-25T23:42:42.913 回答
1

如果您不介意使用像 sed 这样的 perl,它可以使用非常多样化的输入进行复制:

  perl -n -e 's+(<a href=.*?</a>)+ print $1, "\n" +eg;'
于 2012-08-25T23:56:23.430 回答
0

这可能对您有用(GNU sed):

sed '/<a href\>/!d;s//\n&/;s/[^\n]*\n//;:a;$!{/>/!{N;ba}};y/\n/ /;s//&\n/;P;D' file
于 2012-08-26T07:24:28.263 回答