Mehrere Zeilen, die als wörtliche Bash-Variable angegeben sind, nach einer übereinstimmenden Zeile in der Datei anhängen?

Mehrere Zeilen, die als wörtliche Bash-Variable angegeben sind, nach einer übereinstimmenden Zeile in der Datei anhängen?

Ich möchte in einem Bash-Skript mehrere Zeilen nach einer übereinstimmenden Zeile in einer Textdatei anhängen. Mir ist es zwar egal, welches Tool ich für diese Aufgabe wähle, aber wichtig ist mir, dass ich die angehängten Zeilen „so wie sie sind“ im Skript angeben möchte (also ohne eine zusätzliche Datei zu erstellen, die sie enthält), sodass sie in einer Bash-Variable landen und ohne dass ich darin etwas in Anführungszeichen setzen/maskieren muss – und zu diesem Zweck würde die Verwendung eines „in Anführungszeichen gesetzten“ Heredoc für mich funktionieren. Hier ist ein Beispiel 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

Das hier funktioniert leider nicht:

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

... weil sedes fehlschlug, wenn ein nicht maskierter mehrzeiliger Ersatz verwendet wurde. Meine Frage lautet also:

  • Was könnte ich stattdessen verwenden, sedum eine Übereinstimmung für eine Textzeile durchzuführen und die Zeilen wie in der Bash-Variable angegeben ( $REPLACERim Beispiel) einzufügen/anzuhängen?

Antwort1

Wenn Sie GNU verwenden sed, ist die beste Option die Verwendung des rfolgenden Befehls:

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

Antwort2

OK, habe einen Weg gefunden mit 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

Die Ausgabe ist wie gewünscht:

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

verwandte Informationen