Acrescentar várias linhas, especificadas como variável bash literal, após uma linha correspondente no arquivo?

Acrescentar várias linhas, especificadas como variável bash literal, após uma linha correspondente no arquivo?

Gostaria de acrescentar várias linhas após uma linha correspondente em um arquivo de texto em um script bash. Embora eu não me importe particularmente com qual ferramenta escolher para o trabalho, o importante para mim é que eu quero especificar as linhas anexadas "como estão" dentro do script (sem gerar um arquivo adicional que as conteria) para que elas acabar em uma variável Bash, e sem precisar citar/escapar nada nelas - e para esse propósito, usar um heredoc 'citado' funcionaria para mim. Aqui está um exemplo, 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

Infelizmente, isso não funciona:

$ bash appendtest.sh
      "'$oasis$'"
      "'$ocean$'"
      "'$oceanic trench$'"
sed: -e expression #1, char 39: unknown command: `"'

... porque sedfalhou quando uma substituição multilinha sem escape é usada. Então minha pergunta é:

  • O que eu poderia usar em vez de sedrealizar a correspondência em uma linha de texto e inserir/anexar as linhas conforme especificado na variável Bash ( $REPLACERno exemplo)?

Responder1

Se você estiver usando GNU sed, sua melhor opção é usar o rcomando:

sed -i "/    \"'ice field'\"/ r /dev/stdin" mytestfile.txt <<'EOF'
      "'$oasis$'"
      "'$ocean$'"
      "'$oceanic trench$'"
EOF

Responder2

OK, encontrei uma maneira 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

A saída é a desejada:

$ bash appendtest.sh
    "'iceberg'"
    "'ice cliff'"
    "'ice field'"
      "'$oasis$'"
      "'$ocean$'"
      "'$oceanic trench$'"
    "'inlet'"
    "'island'"
    "'islet'"
    "'isthmus'"

informação relacionada