
Me gustaría agregar varias líneas después de una línea coincidente en un archivo de texto en un script bash. Si bien no me importa particularmente qué herramienta elegir para el trabajo, lo importante para mí es que quiero especificar las líneas agregadas "tal cual" dentro del script (sin generar un archivo adicional que las contenga) para que terminar en una variable Bash, y sin tener que citar/escapar nada en ellas, y para ese propósito usar un documento heredoc 'entrecomillado' funcionaría para mí. Aquí hay un ejemplo, appendtest.sh
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
echo "$REPLACER"
sed -i "/ \"'ice field'\"/a${REPLACER}" mytestfile.txt
Lamentablemente esto no funciona:
$ bash appendtest.sh
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
sed: -e expression #1, char 39: unknown command: `"'
... porque sed
falló cuando se utiliza un reemplazo multilínea sin escape. Entonces mi pregunta es:
- ¿Qué podría usar en lugar de
sed
realizar coincidencias en una línea de texto e insertar/añadir las líneas como se especifica en la variable Bash ($REPLACER
en el ejemplo)?
Respuesta1
Si estás usando GNU sed
, tu mejor opción es usar el r
comando:
sed -i "/ \"'ice field'\"/ r /dev/stdin" mytestfile.txt <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
Respuesta2
Bien, encontré una forma usando perl
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
# echo "$REPLACER"
IFS='' read -r -d '' LOOKFOR <<'EOF'
"'ice field'"
EOF
export REPLACER # so perl can access it via $ENV
# -pi will replace in-place but not print to stdout; -p will only print to stdout:
perl -pi -e "s/($LOOKFOR)/"'$1$ENV{"REPLACER"}'"/" mytestfile.txt
# also, with export LOOKFOR, this works:
# perl -pi -e 's/($ENV{"LOOKFOR"})/$1$ENV{"REPLACER"}/' mytestfile.txt
cat mytestfile.txt # see if the replacement is done
La salida es la deseada:
$ bash appendtest.sh
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"