Seite 1 von 1

suchen u. ersetzen mit variablen

Verfasst: 11. Dez 2007 18:46
von bastschuh
Hallo Leute,

ich möchte aus einer Datei einen String durch einen anderen ersetzen.
Da das in einem Script passieren soll, sind diese Strings in einer Varibale eingeschlossen.

Vom Prinzip her wie
sed -i 's/$Variable_1/$Variable_2/g' $DATEI.txt;

aber so funktioniers nicht, sed nimmt keine Variblen?

freu mich auf eine Lösung

Viele Grüße
basti

Verfasst: 12. Dez 2007 7:57
von jochen
Das ist ein typisches Quoting-Problem. $Variable_1 und $Variable_2 sind Shellvariablen, werden also durch die Shell vor dem Start des Kommandos durch ihren Inhalt ersetzt. Dieser Mechanismus ist aber manchmal unerwünscht, weswegen es das Quoting gibt.

"Quoting" heißt nichts anderes als "Liebe Shell, rühre mir den folgenden Bereich nicht an, auch wenn Du dort Sonderzeichen entdeckst". Alles, was Du in Hochkommata einschließt 'wie diesen Text hier' wird von der Shell als Zeichen an und für sich betrachtet. Spaces innerhalb der Hochkommata trennen die Zeichenkette nicht in einzelne Argumente auf, * wirkt nicht als Wildcardzeichen - und $ bewirkt keine Variablenersetzung mehr!

Also: sed kann sowieso keine Variablen wie die meisten UNIX-Tools. Statt dessen gibt es Shellvariablen. Wenn man diese verwenden will, muss man es der Shell aber auch erlauben! Verwende daher mal Anführungszeichen "wie diese hier" statt der Hochkommata:

Code: Alles auswählen

sed -i "s/$Variable_1/$Variable_2/g" $DATEI.txt
Damit hast Du Dein Problem erst mal gelöst. Nur bedenke bitte, dass der Inhalt für sed auch eine Bedeutung haben kann: Enthält Variable_1 beispielsweise den Text "/usr/bin" und Variable_2 den Text "/usr/local/bin", sieht das endgültige Kommando so aus:

Code: Alles auswählen

sed -i s//usr/bin//usr/local/bin/g $DATEI.txt
Und mit dieser Anzahl Slashes kommt sed nicht zurecht. Also vorher entweder die Slashes im Inhalt der Variablen durch "\/" ersetzen oder beim sed das Trennzeichen ändern:

Code: Alles auswählen

sed -i s#/usr/bin#/usr/local/bin#g $DATEI.txt
Dann wären Slashes egal, aber Hashes müssten extra behandelt werden. Wenn Du ein Trennzeichen verwenden kannst, das sonst nicht in den Variablen auftaucht, hast Du gewonnen.

Übrigens, das gilt antürlich auch für alle Zeichen, die als Metazeichen der Regulären Ausdrücke verwendet werden: .[]\*^$

Sowas sauber zu machen ist immer schwierig. Aber wenn Du keinen allzu hohen Ansprüche hast, ist das Problem so lösbar.

Jochen

sed

Verfasst: 12. Dez 2007 8:17
von bastschuh
Hallo Jochen

und vielen Dank :D

Freue mich, dass das so einfach klappt. Ist genau das, was ich wollte:

Code: Alles auswählen

$ echo "/usr/local/alt/bin" > datei.txt
$ A=alt
$ N=neu
$ D=datei
$ sed -i "s/$A/$N/g" $D.txt

$ cat datei.txt
/usr/local/neu/bin

Viele Grüße
bastschuh