[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