[linux-l] Wie kann ich mit sed aus einer Datei lesen und in sie schreiben?
Jan-Benedict Glaw
jbglaw at lug-owl.de
Sa Apr 21 12:53:34 CEST 2012
On Sat, 2012-04-21 10:59:07 +0200, Achim Pabel <Achim.Pabel at gmx.de> wrote:
In dem Script sind mir viele Kleinigkeiten aufgefallen, die machen
können, daß es nicht so läuft, wie erwartet, falls einem User mal
unerwartete Datei- bzw. Verzeichnisnamen unterschieben. Damit meine
ich solche, die allem voran Leerzeichen oder gar Zeilenumbrüche
enthalten.
> #!/bin/bash
[...]
> bindir=`pwd`;
> cd ..
> wdir=`pwd`;
> idwh="index-withframe.html";
Um die `pwd` sollten noch Anführungsstriche stehen, wobei die meisten
heutigen sh-Interpreter (und insbesondere die benutzte bash) das so
machen, wie man das erwarten würde.
> #
> ### 1.) ######################################
> # suche alle index-withframe.html
> #
> for pfad_datei in `find -P oogpm -name $idwh -print`
> do
Solange $idwd nur "index-withframe.html" enthält (oben gesetzt) läuft
das. Es wird aber fehlschlagen, sollte der Dateinamen mal Leerzeichen
enthalten.
Ein weiteres Problem macht die for-Schleife auf, die als Input die von
`find' ausgespuckten Dateinamen enthält. Wenn da mal jemand ein
Verzeichnis anlegt, das Leerzeichen oder Zeilenumbrüche enthält, dann
"zerfällt" für die Schleife der (komplette) Datei-/Verzeichnisname in
die einzelnen, durch Leerzeichen/Zeilenumbrüche getrennten
Einzelkomponenten.
Sowas kann man beispielsweise lösen, indem man
find ... -exec "$0" --do-real-work {} \;
aufruft. Dann startet `find' dieses shell-Script erneut, indem es
--do-real-work (das muß man dann abfragen) sowie den (vollständigen)
Dateinamen übergibt.
> #echo "pfad_datei = <${pfad_datei}";
> pfad=`dirname $pfad_datei`;
> file=`basename $pfad_datei`;
Hier wären Anführungsstriche auch nicht verkehrt.
> cd $pfad;
Hier ebenfalls--sollte $pfad Leerzeichen etc. enthalten. (Wie gesagt:
Die modernen bash-Versionen reagieren so, wie man das erwartet, aber
wenn man mal auf einem älteren System arbeitet oder andere
`sh'-Varianten nutzt, dann fällt einem das auf die Füße.)
> sed 's/classes_list/\.\/usecase\/usecaselisting/' $file > $file.new &
Hier ebenfalls um $file wieder Anführungsstriche.
> wait $!
Aber: Wozu ist das Konstrukt, erst den `sed' in den Hintergrund zu
schieben, nur um dann darauf zu warten?
> mv $file.new $file 2>/dev/null
Anführungsstriche :) Und wozu wird hier die Umleitung von stderr
genutzt? Schlägt das zurück-Umbenennen manchmal fehl?
> # Pruefung ob es das gelinkte Unterverzeichnis gibt.
> if [ -L ./usecae ]; then
^^^^^^^^
> # Hinweis: Manche Verzeichnisse haben von der IC-Nbg "manuell" eine index-withframe.html Datei
> $bindir/cp_templates.sh $bindir ./usecase
^^^^^^^^^
Einer von beiden ist doch bestimmt ein typo, oder?
> # erhalten. Diese Verzeichnisse werden vom Roboter nicht mit gelinkten Unterverzeichniss
> fi
> # hier ./usecase ausgestattet. In diesem Fall darf cp_templates.sh nicht aufgerufen werden.
>
> cd $wdir;
Hier schaden Anführungsstriche ebenfalls nicht.
> done
Ein Hinweis noch zu dem Vorgehen, sich ein Verzeichnis via
variable="`pwd`" zu merken und dann später dahin zurückzuspringen:
Was, wenn das zwischendrin mal gelöscht wird? Sowas kann man
umschiffen:
#!/usr/bin/env sh
./do_something
(
cd "someotherdir"
./dosomethingdifferent
)
./do_something_again
Dann bleibt der Verzeichniswechsel in den Klammern und hat auf
./do_something_again keinen Einfluß. Wenn die Klammer-Zu kommt, ist
der `cd' vergessen.
MfG, JBG
--
Jan-Benedict Glaw jbglaw at lug-owl.de +49-172-7608481
Signature of: Eine Freie Meinung in einem Freien Kopf
the second : für einen Freien Staat voll Freier Bürger.
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : signature.asc
Dateityp : application/pgp-signature
Dateigröße : 198 bytes
Beschreibung: Digital signature
URL : <https://mlists.in-berlin.de/pipermail/linux-l-mlists.in-berlin.de/attachments/20120421/9f6c9210/attachment.sig>
Mehr Informationen über die Mailingliste linux-l