¿Agregar varias líneas, especificadas como variable bash palabra por palabra, después de una línea coincidente en el archivo?

¿Agregar varias líneas, especificadas como variable bash palabra por palabra, después de una línea coincidente en el archivo?

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 sedfalló cuando se utiliza un reemplazo multilínea sin escape. Entonces mi pregunta es:

  • ¿Qué podría usar en lugar de sedrealizar coincidencias en una línea de texto e insertar/añadir las líneas como se especifica en la variable Bash ( $REPLACERen el ejemplo)?

Respuesta1

Si estás usando GNU sed, tu mejor opción es usar el rcomando:

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'"

información relacionada