GNU/Linux >> Tutoriales Linux >  >> Linux

Reemplazo de SED en varias líneas

Solución 1:

Sed funciona línea por línea. Se puede hacer que funcione en varias líneas, pero no fue diseñado de esa manera y, en mi opinión, definitivamente se nota cuando intentas usarlo de esa manera. Pero si decide ir por ese camino, probablemente tendrá que usar registros. Consulte algunas de las soluciones en https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n para ver cómo se puede hacer.

Prefiero usar perl en lugar de sed para este tipo de tarea (orientada a varias líneas, quiero decir). El modelo que debe agregar antes de buscar y reemplazar (BEGIN... ) no es obvio, pero la expresión regular me parece más clara:

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

O, usando la agrupación para acortar la expresión y permitirle usar una expresión regular allí:

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

Debería funcionar tanto en ocurrencias con y sin saltos de línea entre los marcadores de comentario y el código que se va a descomentar.

Adaptado de:

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

Solución 2:

sed lee cada línea por turno, por lo que nunca coincidirá con un patrón de varias líneas a menos que lo empuje en la dirección correcta. El N El comando lee una línea de la entrada y la agrega al espacio del patrón.

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

Podría decirse que si necesita un comando que no sea s , entonces debería cambiar de sed a awk o perl. Aquí hay un fragmento de Perl un poco más flexible que se adapta a los comentarios de varias líneas de una manera más general.

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

Solución 3:

Aquí hay una descripción de los comandos multilínea en SED:http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

Es un dolor en el trasero. Es posible que desee seguir el consejo de Eduardo y usar perl -i -p -e en su lugar.

Solución 4:

  • /<\!--/ :cadena coincidente
  • :X :esta es una etiqueta para el comando de rama "b"
  • /-->/ :cadena coincidente
  • [email protected]@[email protected] :tira "" e imprime el resultado
  • d :eliminar el espacio del patrón y comenzar un nuevo ciclo
  • N :si no coincide con /-->/, agregue una línea
  • bX :rama a :X etiqueta
  • p :simplemente imprime una cadena que no coincide con /