PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Shell: Alle Parameter ab 3 in eine Liste schreiben...



SeeksTheMoon
13-11-2003, 11:41
Ich möchte ein Script schreiben, mit dem man in beliebig vielen Dateien Textstellen durch andere ersetzen kann, und z.B. so aufgerufen wird:

textreplace.sh "Alter Text" "Neuer Text" `find . -type f`

Den Ersetzungs-Teil hab ich erfolgreich mit sed gelöst, aber ich kann das sed-Script nicht einfach auf $@ loslassen, weil es ja auch die ersten beiden Parameter mit den Texten treffen würde und das ist natürlich nicht sinnvoll.
Also brauche ich eine Schleife, die bis auf die ersten beiden Parameter alles aus $@ in eine Liste schreibt:



#!/bin/bash

#hier muss es hin:
#hole aus $@ alles bis auf $1 und $2 und schreibe das in LISTE

for FILE in LISTE;
do
cat $FILE | sed -e 's/$1/$2/g' > $FILE
done

exit 0


Wie mache ich die Schleife?

phate
13-11-2003, 12:01
Verwende 'cut' um aus der Paramterliste alles ab dem 3. Parameter herauszuschneiden.
for FILE in `echo $@ | cut -d" " -f 3-`
do
cat $FILE | sed -e 's/$1/$2/g' > $FILE
doneEinziges Manko dieser Vorgehensweise ist das Du jede Datei in der Paramterangabe auch wirklich nur durch ein Leerzeichen trennen darfst. Stört Dich das, dann musst Du mit awk oder perl arbeiten.

Die Art und Weise, in der Du die Ersetzung vornimmst ist übrigens nicht ganz sicher. Ist der Puffer für die Pipe voll, über die Du die Eingabedaten übergibst, dann wird sed mit den Eingabedaten gefüttert und beginnt schon munter fröhlich, Deine Eingabedatei zu überschreiben, ungeachtet evtl. noch vorhandener Folgedaten.

Sicherer ist es die Änderungen in eine temporäre Datei zu schreiben und diese nach erfolgreicher Ersetzung über die alte zu schieben.
cat $FILE | sed -e 's/$1/$2/g' > ${FILE}.tmp && mv ${FILE}.tmp $FILE

SeeksTheMoon
13-11-2003, 12:29
ok, das klappt so sehr gut, aber ich hab beim sed doch noch einen Fehler.
Der Befehl selber klappt so, wenn man direkt mit Werten arbeitet, aber sed scheint das $1 und $2 als sed-Muster zu interpretieren, dabei soll das ja die Shell ersetzen. Ich kriege das auch nicht geschützt; weder mit \ noch sonstwie.
Vielleicht sollte ich es doch lieber mit awk machen.

SeeksTheMoon
13-11-2003, 12:59
ach, war nur ne Kleinigkeit: man schützt Shellvariablen in sed mit ' ' und nicht anders. So sieht das fertige Script aus:


#!/bin/bash

if [ ! $# -ge 3 ]
then
echo "Zu wenig Paramameter!"
echo
echo "Anwendung: $0 Suchtext Ersetzung Dateiliste"
echo
echo "Zuerst wird der alte, zu ersetzende Text angegeben,"
echo "dann der Text der diesen überschreiben soll, gefolgt von 1+n Dateien"
exit 1
fi

for FILE in `echo $@ | cut -d " " -f 3-`
do
echo -n "Bearbeite Datei $FILE..."
cat $FILE | sed -e 's/'$1'/'$2'/g' > ${FILE}.tmp && mv ${FILE}.tmp $FILE
echo "fertig!"
done
exit 0

fork
14-11-2003, 14:18
> man schützt Shellvariablen in sed mit ' '

Na ja fast richtig...
's/'$1'/'$2'/g' Die Shell ist mit der Verarbeitung der Kommandozeile als erstes dran.

Dein Problem war nun das Du die Shellvariablen vor der Shell geschützt hast. Die Zusätzlichen Hochkommata haben dann wie man sieht den geschützten Bereich vor der Variable geschlossen und danach wieder aufgemacht.