Tengo que reemplazar un bloque grande de texto (código de script de shell) en un archivo con otro bloque de texto.
Estoy impresionado con el ¿Cómo puedo usar sed para reemplazar una cadena de varias líneas? respondido por antak y Multi-line replace respondido por Bruce Ediger
Pero tengo algunos problemas para usarlos.
antak ya mencionó en su respuesta que transmitir archivos completos (
1h;2,$H;$!d;g;) al búfer no es recomendable para archivos grandes, porque sobrecarga la memoria.Sé que
sedse puede usar con la función de bloque para preservar el texto fuera del bloque sin cambios. Quiero usar esta función Pero si lo uso,sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename
insertará texto nuevo (código) repetidamente para cada transmisión. Por lo tanto, tengo que hacer el bloque visual como una secuencia, usando algo similar a lo sugerido por antak anteriormente, pero para el bloque (no para todo el archivo).
Como mencionó Bruce Ediger, se puede probar la función de agregar
exque comienza con elafinal con.(punto), pero mi nuevo texto (código) contiene líneas que comienzan con un punto, que puede considerarse como el punto de sintaxis de adición. ¿Cómo puedo usarlo en esta situación?ex'sdd' número de líneas 'puede eliminar varias líneas, pero si tengo un bloque entre / marker1 / y / marker2 / con el número de líneas no fijo (variable) se debe reemplazar con un nuevo texto (código), cómo hacerlo eso ?

sedoexcomando funciona).rel comando leer archivo para copiar el texto de otro archivo, si la fuente del texto de reemplazo está en un archivo.Respuestas:
Sugiero usar el comando c hange (que es esencialmente un d elete junto con un a ppend, aunque el apéndice solo se aplica a la última línea en el rango que es exactamente lo que desea aquí):
Aquí usando
sedla sintaxis de GNU para la edición in situ (-i). Eseccomando es, por lo demás, estándar y portátil. GNUsedsoporta:como una extensión no estándar.
Los caracteres de nueva línea y barra invertida deben escapar (con barra invertida) en el texto de reemplazo.
fuente
sedyexpor igual. Muchas gracias.sedcomo en el caso de laexsintaxis sugerida por Bruce Ediger en el reemplazo de varias líneas .rcomando discutido en otras respuestas a esa pregunta. No estoy seguro de cómo usarías un documento aquísed.Usando GNU sed
Para reemplazar líneas que comienzan una coincidencia de línea
3y continúan a una línea que coincide5conNew Code:Para las líneas en el rango
/3/,/5/, probamos para ver si la línea coincide5(lo que significa que esta es la última línea del grupo) y, de ser así, hacemos la sustitución para insertarNew Code. Si se realizó la sustitución, eltcomando le dice a sed que salte al final de los comandos (en cuyo casoNew Codese imprime). Si no, eldcomando le dice a sed que elimine la línea.Todas las demás líneas se imprimen normalmente.
Para cambiar el archivo en su lugar,
-ise puede usar la opción:Usando awk
Para hacer lo mismo usando awk:
El comando awk trata especialmente las líneas del rango
/3/,/5/. Para líneas en ese rango, probamos para ver sifes cero (es decir, si!fes verdadero) y, si es así, imprimimosNew Codey establecemosfen 1 y luego omitimos el resto de los comandos y saltamos a lanextlínea.Para líneas fuera del rango
/3/,/5/, no se realiza ningún salto y esto1hace que se imprima la línea. En más detalle,1es una condición. Como1no es cero, la condición se evalúa como verdadera. Como no se asocia ninguna acción con la condición, se realiza la acción predeterminada, que es imprimir la línea. Por1lo tanto, es una forma abreviada de imprimir la línea.Para cambiar un archivo en su lugar, la
-i inplaceopción se puede usar con GNUawk4.1 o superior:fuente
awk, ¿podría explicarme un poco suawkexpresiónsed '/3/,/4/d;/5/cNew Code'awk '/5/{print "New Code"}/3/,/5/{next}1'Basado en la discusión anterior, llego a una solución usando
exLo anterior da
Gracias g-man por informarme sobre el comando de cambio y dar aclaraciones sobre dot. Ambos
sedyexcomparten una sintaxis casi similar para el comando de cambio (también para el comando eliminar, agregar comando, etc.).fuente