Verwenden Sie den sed-Befehl mit Variablen

Verwenden Sie den sed-Befehl mit Variablen

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 sedBefehl 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 echoBefehle 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, atritt 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 -xwü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

  • -ibedeutet „Ersetzen an Ort und Stelle“. Wenn Sie „Ersetzen“ nicht verwenden, -ierfolgt es in der Standardausgabe.

verwandte Informationen