如何打印只与sed匹配?

时间:2012-08-25 23:27:53

标签: regex macos bash sed terminal

好的,这很简单,但我无法理解。

基本上我想从一个大的<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 个答案:

答案 0 :(得分:2)

匹配整行,将有趣的部分放在一个组中,替换为该组的内容。使用-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时,use an HTML parser

答案 1 :(得分:1)

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

  sed -e 's_.*<a href=_<a href=_' -e 's_>.*_>ed <<'EOF'
 -e 's_.*<a href=_<a href=_' -e 's_>.*_>_'

答案 2 :(得分:1)

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

  perl -n -e 's+(<a href=.*?</a>)+ print $1, "\n" +eg;'

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed '/<a href\>/!d;s//\n&/;s/[^\n]*\n//;:a;$!{/>/!{N;ba}};y/\n/ /;s//&\n/;P;D' file