2011-05-02 418 views
11

我嘗試使用sed替換文件的html元素的每一個其他元素,這樣我就可以創建交替的顏色行。Sed替換第n個匹配項

這是我所嘗試過的,它不起作用。

sed 's/<tr valign=top>/<tr valign=top bgcolor='#E0E0E0'>/2' untitled.html 

回答

10

我使用awk解決它:

awk '/<tr valign=top>/&&v++%2{sub(/<tr valign=top>/, "<tr valign=top bgcolor='#E0E0E0'>")}{print}' untitled.html 

首先,它驗證如果行包含<tr valign=top>

/<tr valign=top>/&&v++%2 

以及是否<tr valign=top>是一個奇怪的發現,比如:

v++%2 

如果是這樣,它取代了<tr valign=top>在線路

{sub(/<tr valign=top>/, "<tr valign=top bgcolor='#E0E0E0'>")} 

由於所有行被要被打印時,存在總是會被執行(對於所有線)和將打印當前線的塊:

{print} 
3

這個工作對我來說:

sed -e "s/<tr/<TR bgcolor='#E0E0E0'/g;n" simpletable.htm 

樣本輸入:

<table> 
    <tr><td>Row1/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row2/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row3/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row4/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row5/col1</td><td>col2</td><td>col3</td></tr> 
</table> 

輸出樣本:

<table> 
    <TR bgcolor='#E0E0E0'><td>Row1/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row2/col1</td><td>col2</td><td>col3</td></tr> 
    <TR bgcolor='#E0E0E0'><td>Row3/col1</td><td>col2</td><td>col3</td></tr> 
    <tr><td>Row4/col1</td><td>col2</td><td>col3</td></tr> 
    <TR bgcolor='#E0E0E0'><td>Row5/col1</td><td>col2</td><td>col3</td></tr> 
</table> 

的關鍵是使用在SED的n命令,它前進到下一行。 這隻有在TR佔據不同的行時纔有效。 它會與嵌套表格分開,或者如果單行有多個TR。

+0

另外,這個命令只有在除了'tr's之外什麼都沒有,對嗎? 'tr'應該在同一行開始和結束,並且不能在它們之間有空行。我對嗎? (儘管如此,我發現你的解決方案非常具有啓發性,因爲我不習慣'n'命令)。 – brandizzi 2011-05-02 14:37:36

+0

它取代每一個奇怪的事件,但如何改變它每一次偶發生? – Offenso 2016-08-16 21:17:45

0

根據http://www.linuxquestions.org/questions/programming-9/replace-2nd-occurrence-of-a-string-in-a-file-sed-or-awk-800171/

試試這個。

sed '0,/<tr/! s/<tr/<TR bgcolor='#E0E0E0'/' file.txt 

感嘆號否定了一切從文件中的第一個「傑克」的開頭,從而替代以下所有線路運行。請注意,我相信這只是一個gnu sed操作。

如果您只需要在第二次出現時進行操作,並忽略任何後續匹配,則可以使用嵌套表達式。

sed '0,/<tr/! {0,/<tr/ s/<tr/<TR bgcolor='#E0E0E0'/}' file.txt 

這裏,括號內的表達式將在所述第一部分的輸出進行操作,但在這種情況下,它會改變第一匹配「傑克」之後退出。

PS,我發現sed faq在這種情況下非常有用。