2011-05-02 26 views
11

Estoy tratando de usar sed para reemplazar cualquier otra aparición de un elemento html de un archivo para poder hacer filas de color alternas.Sed reemplazar cada enésima ocurrencia

Esto es lo que he intentado y no funciona.

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

Respuesta

10

Me solucionarlo con awk:

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

primer lugar, se verifica si la línea contiene <tr valign=top>

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

y si el <tr valign=top> es un caso raro encontrado:

v++%2 

Si es así, que sustituye a la <tr valign=top> en la línea

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

Dado que se van a imprimir todas las líneas, hay un bloque que siempre va a ser ejecutado (para todas las líneas) y se imprimirá la línea actual:

{print} 
3

Esto funciona para mí: entrada

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

muestra:

<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> 

resultado de ejemplo:

<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> 

La clave es usar el comando n en SED, que avanza a la siguiente línea. Esto funciona solo si el TR ocupa distintas líneas. Se romperá con tablas anidadas, o si hay múltiples TR en una sola línea.

+0

Además, este comando funciona solo si no hay nada excepto 'tr's en la fila, ¿verdad? El 'tr' debe comenzar y terminar en la misma línea y no puede tener líneas vacías entre ellos. ¿Estoy en lo cierto? (No obstante, su solución es muy instructiva porque no estoy acostumbrado al comando 'n'). – brandizzi

+0

Reemplaza todas las apariciones impares, pero ¿cómo modificarlas para cada aparición regular? – Offenso

0

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

Prueba esto.

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

signo de exclamación El niega todo, desde el principio del archivo a la primera "Jack", por lo que la sustitución opera en todas las líneas siguientes. Tenga en cuenta que creo que esto es solo una operación de gnu sed.

Si necesita operar solo la segunda vez e ignorar cualquier coincidencia posterior, puede usar una expresión anidada.

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

Aquí, la expresión entre corchetes operará en la salida de la primera parte, pero en este caso, se terminará después de cambiar la primera coincidencia "Jack".

PD, encontré que el sed faq fue muy útil en casos como este.

Cuestiones relacionadas