2012-08-25 81 views
2

好的,這是一個容易的,但我無法弄清楚。如何打印只與sed匹配?

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

我試圖用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。我知道我的正則表達式不是最靈活的,但對我的意圖已經足夠了。

+2

是'sed'一個需求? ('grep -o')? –

+0

謝謝,這也適用。我仍然想知道sed是否可能。 – DrummerB

回答

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

假設有每行下面可能只工作一個超鏈接...

 sed -e 's_.*&lta href=_&lta href=_' -e 's_>.*_>ed <<'EOF' 
-e 's_.*&lta href=_&lta href=_' -e 's_>.*_>_'
+0

不幸的是,並非如此:( – DrummerB

1

如果你像sed它可以用非常不同的輸入複製不介意用perl:

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

這可能會爲你工作(GNU SED):

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