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
sed
se 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
ex
que comienza con ela
final 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 ?
sed
oex
comando funciona).r
el 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
sed
la sintaxis de GNU para la edición in situ (-i
). Esec
comando es, por lo demás, estándar y portátil. GNUsed
soporta: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
sed
yex
por igual. Muchas gracias.sed
como en el caso de laex
sintaxis sugerida por Bruce Ediger en el reemplazo de varias líneas .r
comando 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
3
y continúan a una línea que coincide5
conNew 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, elt
comando le dice a sed que salte al final de los comandos (en cuyo casoNew Code
se imprime). Si no, eld
comando 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,
-i
se 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 sif
es cero (es decir, si!f
es verdadero) y, si es así, imprimimosNew Code
y establecemosf
en 1 y luego omitimos el resto de los comandos y saltamos a lanext
línea.Para líneas fuera del rango
/3/,/5/
, no se realiza ningún salto y esto1
hace que se imprima la línea. En más detalle,1
es una condición. Como1
no 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. Por1
lo tanto, es una forma abreviada de imprimir la línea.Para cambiar un archivo en su lugar, la
-i inplace
opción se puede usar con GNUawk
4.1 o superior:fuente
awk
, ¿podría explicarme un poco suawk
expresió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
ex
Lo anterior da
Gracias g-man por informarme sobre el comando de cambio y dar aclaraciones sobre dot. Ambos
sed
yex
comparten una sintaxis casi similar para el comando de cambio (también para el comando eliminar, agregar comando, etc.).fuente