Добавить несколько строк, указанных как буквальная переменная bash, после совпавшей строки в файле?

Добавить несколько строк, указанных как буквальная переменная bash, после совпавшей строки в файле?

Я хотел бы добавить несколько строк после совпавшей строки в текстовом файле в скрипте bash. Хотя мне не особо важно, какой инструмент выбрать для этой работы, для меня важно то, что я хочу указать строки, добавленные "как есть" внутри скрипта (то есть без создания дополнительного файла, который бы их хранил), чтобы они попали в переменную Bash, и без необходимости цитировать/экранировать что-либо в них - и для этой цели мне подойдет использование heredoc с кавычками. Вот пример 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

К сожалению, это не работает:

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

... потому что sedне удалось, когда использовалась неэкранированная многострочная замена. Поэтому мой вопрос:

  • Что я мог бы использовать вместо этого sedдля сопоставления строк текста и вставки/добавления строк, как указано в переменной Bash ( $REPLACERв примере)?

решение1

Если вы используете GNU sed, лучшим вариантом будет использовать rкоманду:

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

решение2

Хорошо, нашел один способ с помощью 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

Вывод такой, как и хотелось бы:

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

Связанный контент