shell - lineas - Insertar línea después del primer partido usando sed
sed linux (6)
Por alguna razón, parece que no puedo encontrar una respuesta directa a esto y estoy en un momento de crisis en este momento. ¿Cómo voy a insertar una línea de texto de elección después de la primera línea que coincida con una cadena específica usando el comando sed
? Yo tengo ...
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
Y quiero insertar una línea después de CLIENTSCRIPT=
línea que da como resultado ...
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
El comando Sed que funciona en MacOS (al menos, OS 10) y Unix por igual (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 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 old / POSIX sed. 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 volver a trabajar 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, sin volver nunca al primer comando sed).
Es posible que observe que agregué un ''^ *'' al patrón coincidente en caso de que la línea aparezca en un comentario, por ejemplo, o tenga sangría. No es 100% perfecto, pero cubre algunas otras situaciones que probablemente sean comunes. Ajustar según sea necesario ...
Estas dos soluciones también solucionan el problema (para la solución genérica de agregar una línea) que si la nueva línea insertada contiene barras invertidas o símbolos de exclusión, serán interpretados por sed y probablemente no salgan igual, como el /n
es - p.ej. /0
sería la primera línea emparejada. Especialmente útil si agrega una línea que proviene de una variable donde, de lo contrario, tendría que escapar de todo primero usando $ {var //} antes, u otra declaración sed, etc.
Esta solución es un poco menos complicada en las secuencias de comandos (sin embargo, las citas y / n no son fáciles de leer), cuando no desea poner 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 $ ''/ n'' se evalúa en una nueva línea por el shell, no en los valores normales ''/ n'' de una sola cita.
Sin embargo, es lo suficientemente largo como para pensar que perl / incluso awk podría ganar debido a que es más legible.
Intenta hacer esto usando gnu sed :
sed ''/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"'' file
si desea sustituirlo en el lugar , use
sed -i ''/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"'' file
Salida
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
Doc
- ver sed doc y buscar
/a
(adjuntar)
Recientemente tuve que lidiar con esto, pero no solo por un archivo sino por varios archivos diferentes que simplemente no podía hacer a mano. Así que tuve que encontrar un script para eso.
Script Descargar: kinglazy-autoinsert.sh
Uso:
kinglazy-autoinsert.sh (list_file) (pattern_file)
Explicación de los parámetros:
list_file = Este es el archivo que contiene la ruta absoluta de la lista de archivos que desea editar
pattern_file = Este es el archivo donde especifica el patrón (en la primera columna) bajo el cual desea agregar texto nuevo. El nuevo texto para agregar bajo el patrón se especifica en la segunda columna. ¡Y eso es todo!
Este script ahorra tiempo y te ayuda a realizar el trabajo con el menor esfuerzo posible.
Dependencias: ninguna
Tenga en cuenta la sintaxis sed
estándar (como en POSIX, por lo que es compatible con todas las implementaciones de sed
conforme (GNU, OS / X, BSD, Solaris ...)):
sed ''/CLIENTSCRIPT=/a/
CLIENTSCRIPT2="hello"'' file
La opción -i
para la edición in situ también es una extensión de GNU, algunas otras implementaciones (como las de FreeBSD) admiten -i ''''
para eso.
Alternativamente, para la portabilidad, puede usar perl
lugar:
perl -pi -e ''$_ .= qq(CLIENTSCRIPT2="hello"/n) if /CLIENTSCRIPT=/'' file
O puede usar ed
o ex
:
printf ''%s/n'' /CLIENTSCRIPT=/a ''CLIENTSCRIPT2="hello"'' . w q | ex -s file
Tuve una tarea similar y no pude lograr que la solución perl anterior funcionara.
Aquí está mi solución:
perl -i -pe "BEGIN{undef $/;} s/^/[mysqld/]$/[mysqld]/n/ncollation-server = utf8_unicode_ci/n/sgm" /etc/mysql/my.cnf
Explicación:
Utiliza una expresión regular para buscar una línea en mi archivo /etc/mysql/my.cnf que contenía solo [mysqld]
y lo reemplazó con
[mysqld] collation-server = utf8_unicode_ci
agregando de manera efectiva la collation-server = utf8_unicode_ci
después de la línea que contiene [mysqld]
.
Un one-liner compatible con POSIX:
sed ''/CLIENTSCRIPT="foo"/s/.*/&/nCLIENTSCRIPT2="hello"/'' file