2011-05-02 173 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在这种情况下非常有用。