Insertar línea después de la coincidencia usando sed
Por alguna razón, parece que no puedo encontrar una respuesta sencilla a esto y estoy en un poco de poco tiempo en este momento. ¿Cómo haría para insertar una línea de texto seleccionada después de la primera línea que coincida con una cadena específica usando el sed
comando? Tengo ...
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
Y quiero insertar una línea después de la CLIENTSCRIPT=
línea que da como resultado...
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
Intente hacer esto usando GNU sed:
sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
si desea sustituir in situ , utilice
sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
Producción
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
Doc
- ver sed doc y buscar
\a
(añadir)
Tenga en cuenta la sed
sintaxis estándar (como en POSIX, por lo que es compatible con todas sed
las implementaciones conformes (GNU, OS/X, BSD, Solaris...)):
sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file
O en una línea:
sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file
( -e
Las expresiones (y el contenido de -f
los archivos) se unen con nuevas líneas para formar las sed
interpretaciones del script sed).
La -i
opción para la edición in situ también es una extensión de GNU, algunas otras implementaciones (como la de FreeBSD) -i ''
la admiten.
Alternativamente, para portabilidad, puedes usar perl
en su lugar:
perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file
O podrías usar ed
o ex
:
printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file
Comando Sed que funciona tanto en MacOS (al menos, OS 10) como en Unix (es decir, no requiere gnu sed como el de Gilles (actualmente aceptado):
sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file
Esto funciona en bash y tal vez también en otros shells que conocen el estilo de cotización de evaluación $'\n'. Todo puede estar en una línea y funcionar en comandos sed más antiguos/POSIX. Si puede haber varias líneas que coincidan con CLIENTSCRIPT="foo" (o su equivalente) y desea agregar solo la línea adicional la primera vez, puede reelaborarlo de la siguiente manera:
sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file
(Esto crea un bucle después del código de inserción de línea que simplemente recorre el resto del archivo y nunca vuelve al primer comando sed).
Quizás notes que agregué un '^ *' al patrón coincidente en caso de que esa línea aparezca en un comentario, digamos, o tenga sangría. No es 100% perfecto, pero cubre otras situaciones que probablemente sean comunes. Ajuste según sea necesario...
Estas dos soluciones también solucionan el problema (para la solución genérica de agregar una línea) de que si su nueva línea insertada contiene barras invertidas o símbolos comerciales sin escape, sed los interpretará y probablemente no saldrán igual, como is, por \n
ejemplo. \0
sería la primera línea coincidente. Especialmente útil si estás agregando una línea que proviene de una variable donde de otro modo tendrías que escapar de todo primero usando ${var//} antes, u otra declaración sed, etc.
Esta solución es un poco menos complicada en los scripts (aunque las comillas y \n no son fáciles de leer), cuando no desea colocar el texto de reemplazo para el comando a al comienzo de una línea, por ejemplo, en una función. con líneas sangradas. He aprovechado que el shell evalúa $'\n' como una nueva línea, no en valores normales entre comillas simples '\n'.
Sin embargo, se está haciendo lo suficientemente largo como para que creo que perl/incluso awk podría ganar debido a que es más legible.