
Ich habe jede mögliche Lösung ausprobiert, die auf Stack Overflow und den zugehörigen Websites verfügbar ist, aber keine Lösung gefunden. Ich habe eine ganze Weile mit diesem Problem verbracht und stelle diese Frage nun endlich.
Ich möchte den sed
Befehl mit Shell-Variablen verwenden. Mein Skript ist ziemlich einfach:
## string to replace is the text after comma in the variable pc.
to_replace=${pc#*,}
echo $to_replace
##text to be replaced by the following line
replace_with="PARTITIONED BY ($pc1);"
echo $replace_with
## use sed command to replace.
sed "s@$to_replace@$replace_with@" $entry ## $entry is the variable that contains the file name
Die beiden echo
Befehle liefern jeweils folgende Ausgaben:
PARTITIONEDED BY (date_key ); ## the text I want to be replaced
PARTITIONED BY ( date_key int ); ## the text I want to replace with
Ich erhalte entweder eine Fehlermeldung:
sed: -e expression #1, char 2: unterminated `s' command
oder der Text wird überhaupt nicht ersetzt.
Kann mir bitte jemand helfen? Ich verwende Centos 6 (falls das wichtig ist). Vielen Dank im Voraus!
Antwort1
sed: -e expression #1, char 2: unterminated `s' command
Die Fehlermeldung besagt, dass der Fehler beim zweiten Zeichen auftritt, was merkwürdig erscheint. Ich kann dies reproduzieren, indem ich am Anfang der ersten Variable eine neue Zeile einfüge:
$ a=$'\nfoo'
$ b='bar'
$ sed "s@$a@$b@"
sed: -e expression #1, char 2: unterminated `s' command
Ein nicht maskierter Zeilenumbruch beendet den sed-Befehl. Wenn der Zeilenumbruch später eingefügt wird, a
tritt der Fehler natürlich bei einem späteren Zeichen auf.
Sie haben beide Variablen zuvor im Skript ausgedruckt, sie waren jedoch nicht in Anführungszeichen gesetzt, sodass alle führenden Leerzeichen darin entfernt worden wären und Leerzeichen in der Mitte als einzelne Leerzeichen angezeigt würden.
Überprüfen Sie, was Ihre Variablen tatsächlich enthalten, etwa folgendermaßen:
printf ">%s<\n" "$to_replace"
printf "%q\n" "$to_replace"
Letzteres ist eine Bash-Funktion, die die Zeichenfolge in Anführungszeichen auf eine Weise anzeigt, die Bash als Eingabe akzeptiert. set -x
würde auch anzeigen, was an die Befehlszeile von sed geht, aber Sie müssten auf den wörtlichen Zeilenumbruch in der Ausgabe achten.
Wenn also nur ein einziger führender Zeilenumbruch vorhanden ist, können Sie ihn am Anfang des Skripts entfernen:
to_replace=${pc#*,}
to_replace=${to_replace#$'\n'}
(Sie könnten diese zu einem kombinieren, aber separate Schritte funktionieren auch, wenn die neue Zeile nicht vorhanden ist.)
Antwort2
Versuche dies
sed -i -e "s@$to_replace@$replace_with@g" "$entry"
Wo
-i
bedeutet „Ersetzen an Ort und Stelle“. Wenn Sie „Ersetzen“ nicht verwenden,-i
erfolgt es in der Standardausgabe.