
Utilizo scripts de shell para configurar diferentes tipos de máquinas virtuales. A menudo, estos scripts incluyen variables multilínea que deben insertarse en archivos de configuración en determinadas posiciones mediante sed
.
Si los creo así, todo está bien:
VAR="Config Line1\nConfig Line2\nConfig Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile
Sin embargo, esto no hace que el script sea muy legible, especialmente porque los bloques de texto pueden ser bastante largos.
Si los escribo así:
VAR="Config Line1
Config Line2
Config Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile
Recibo un error al ejecutar el script: sed: -e expression #1, char 31: unknown command:
C''
¿Hay alguna manera de usarlo sed
con variables declaradas así?
Respuesta1
La sintaxis estándar del a
comando es:
sed -e 'a\
first line\
second line\
last line'
BSD (al menos FreeBSD y OS/X) sed
elimina los espacios en blanco principales, ynecesita el -e
para solucionar un error. GNU sed
permite mover la primera línea justo después de a\
siempre que no esté vacía.
Entonces, necesitarías preprocesar la entrada:
VAR='content with
multiple lines
some with lead blanks
or even backslash\'
preprocessed_VAR=$(printf '%s\n' "$VAR" |
sed 's/\\/&&/g;s/^[[:blank:]]/\\&/;s/$/\\/')
sed -i -e "/MatchingPattern/a\\
${preprocessed_VAR%?}" somefile
(reemplazar -i
con -i ''
en FreeBSD o OS/X).
En GNU/Linux y con el shell GNU ( bash
) o zsh
, puedes hacer en su lugar:
sed -i '/MatchingPattern/r /dev/stdin' <<< "$VAR"
Eso funciona porque bash
e zsh
implementar here-strings con archivos temporales eliminados y /dev/stdin en Linux se implementa como un enlace simbólico al archivo (lo que significa que se puede abrir varias veces y cada vez, se abre al principio).
Aquí también puedes usar GNU awk
en su lugar:
(export VAR
gawk -i /usr/share/awk/inplace.awk '{print}; /MatchingPattern/{print ENVIRON["VAR"]}' somefile)
No utilice-i inplace
as gawk
intenta cargar primero la inplace
extensión (como inplace
o inplace.awk
) desde el directorio de trabajo actual, donde alguien podría haber colocado malware. La ruta de la inplace
extensión suministrada gawk
puede variar según el sistema; consulte el resultado degawk 'BEGIN{print ENVIRON["AWKPATH"]}'
O perl
(de donde -i
viene eso):
(export VAR
perl -pi -e '$_ .= "$ENV{VAR}\n" if /MatchingPattern/' somefile)
Respuesta2
El error se debe a que el sed
comando agregar a
necesita una barra invertida después de lo real a
:
Con GNU sed
:
$ sed "/pattern/a\\$VAR" file.in >file.out
BSD sed
, hasta donde yo sé, solo puede insertar una sola línea en un archivo con el a
comando, a menos que las nuevas líneas se escapen correctamente.
Respuesta estrechamente relacionada sobre cómo resolver esto con BSD sed
:http://unix.stackexchange.com/a/60322