Domanda Sed sostituisce ogni ennesimo evento


Sto cercando di usare sed per sostituire ogni altra occorrenza di un elemento html di un file in modo da poter creare righe di colore alternate.

Ecco cosa ho provato e non funziona.

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

11
2018-05-02 14:11


origine


risposte:


Lo risolverei con awk:

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

In primo luogo, verifica se la riga contiene <tr valign=top>

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

e se il <tr valign=top> è un'istanza trovata dispari:

v++%2

Se è così, sostituisce il <tr valign=top> nella linea

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

Poiché tutte le righe devono essere stampate, esiste un blocco che verrà sempre eseguito (per tutte le linee) e stamperà la riga corrente:

{print}

10
2018-05-02 14:29



Questo funziona per me:

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

esempio di input:

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

uscita di esempio:

<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 chiave è usare il n comando in sed, che avanza alla riga successiva. Funziona solo se il TR occupa linee distinte. Si romperà con le tabelle nidificate o se ci sono più TR su una singola riga.


3
2018-05-02 14:32



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

Prova questo.

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

Il punto esclamativo annulla tutto dall'inizio del file al primo "Jack", in modo che la sostituzione funzioni su tutte le righe seguenti. Si noti che ritengo che questa operazione sia solo Gnu.

Se è necessario operare solo sulla seconda occorrenza e ignorare eventuali corrispondenze successive, è possibile utilizzare un'espressione nidificata.

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

Qui, l'espressione tra parentesi funzionerà sull'output della prima parte, ma in questo caso, uscirà dopo aver modificato il primo "Jack" corrispondente.

PS, ho trovato il sed faq essere molto utile in casi come questo.


0
2017-08-16 21:20