GNU/Linux >> Linux Esercitazione >  >> Linux

Sostituzione SED su più righe

Soluzione 1:

Sed funziona riga per riga. Può essere fatto funzionare su più linee, ma non è stato progettato in questo modo - e secondo me si vede sicuramente quando si tenta di usarlo in quel modo. Ma se decidi di andare in quel modo probabilmente dovrai usare i registri. Controlla alcune delle soluzioni a https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n per vedere come si può fare.

Preferisco usare perl invece di sed per questo tipo di attività (orientata a più righe, intendo). Il boilerplate che devi aggiungere prima della ricerca e sostituzione (BEGIN... ) non è ovvio, ma la regex mi sembra più pulita:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Oppure, usando il raggruppamento per abbreviare l'espressione e per permetterti di usare una regex lì:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml

Dovrebbe funzionare sia su occorrenze con che senza newline tra i marcatori di commento e il codice da decommentare.

Adattato da:

https://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

Soluzione 2:

sed legge ogni riga a turno, quindi non corrisponderà mai a uno schema multilinea a meno che non lo spingi nella giusta direzione. Il N Il comando legge una riga dall'input e la aggiunge allo spazio del pattern.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Probabilmente, se hai bisogno di un comando diverso da s , allora dovresti passare da sed a awk o perl. Ecco uno snippet Perl leggermente più flessibile che gestisce i commenti su più righe in modo più generale.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml

Soluzione 3:

Ecco una descrizione dei comandi multilinea in SED:http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

È un rompicoglioni. Potresti voler seguire il consiglio di Eduardo e usare perl -i -p -e invece.

Soluzione 4:

  • /<\!--/ :stringa corrispondente
  • :X :questa è un'etichetta per il comando ramo "b"
  • /-->/ :stringa corrispondente
  • [email protected]@[email protected] :elimina "" e stampa il risultato
  • d :elimina lo spazio del modello e avvia un nuovo ciclo
  • N :se non corrisponde a /-->/ allora aggiungi una riga
  • bX :ramo a :X label
  • p :basta stampare una stringa che non corrisponde a /