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 risultatod
:elimina lo spazio del modello e avvia un nuovo cicloN
:se non corrisponde a /-->/ allora aggiungi una rigabX
:ramo a :X labelp
:basta stampare una stringa che non corrisponde a /