
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 sed
es fehlschlug, wenn ein nicht maskierter mehrzeiliger Ersatz verwendet wurde. Meine Frage lautet also:
- Was könnte ich stattdessen verwenden,
sed
um eine Übereinstimmung für eine Textzeile durchzuführen und die Zeilen wie in der Bash-Variable angegeben ($REPLACER
im Beispiel) einzufügen/anzuhängen?
Antwort1
Wenn Sie GNU verwenden sed
, ist die beste Option die Verwendung des r
folgenden 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'"