Am Donnerstag, 14. Oktober 2004 17:29 schrieb Dr. Jürgen Vollmer:
On Thursday 14 October 2004 15:17, Dirk Meier wrote:
Hallo, ich versuche mit: find . -name *ä* -exec mv -v {} `echo {} | sed 's/ä/ae/'` \; Dateien mit Umlauten umzubenennen. Als Ergebnis obigen Befehls erhalte ich: "./testä und ./testä sind die gleiche Datei". Es sieht so aus, dass die Kommandosubstitution nich funktioniert. Aber warum nicht? Dirk
ein set +x vor der Ausfühung des Kommandos gibt den Grund daf+ür an: ------ ++ echo '{}' ++ sed s/ä/ae/g + find . -name testä -exec echo mv -v '{}' '{}' ';' mv -v ./testä ./testä ------
das `echo {} | sed 's/ä/ae/'` wird natürlich ausgewertet, _bevor_ das find-exec ausgeführt wird. Ist ja auch klar, denn es steht ja auch da: find ... `echo...` `..` wird zuerst ausgewertet, bevor das Kommando ausgeführt wird.
Wenn man das machen will dann doch einfacher (und allgemeiner):
for f in `find $DIR -regex ".*[äöüAÖÜ].*"` do mv $f `echo $f | sed -e"s/ä/ae/g" -e"s/ö/oe/g" -e"s/ü/ue/g" \ -e"s/Ä/Ae/g" -e"s/Ö/Oe/g" -e"s/Ü/Ue/g"` done
Jürgen
------- Hallo Jürgen, das ist eine schöne Lösung und funktioniert einwandfrei. Leider ist bei der Ausführung ein weiteres Problem aufgetaucht. Es existieren auch Dateinamen, die Leerzeichen enthalten. for f in `find $DIR -regex ".* .*"` do mv $f `echo $f | sed -e"s/ /_/g"` done funktioniert nicht, da mv die Dateinamen mit Leerzeichen als mehrere Dateinamen interpretiert. Gibt es da auch eine einfache Lösung? Außerdem habe ich den ersten Teil mit set +x nicht verstanden. Kannst Du dass bitte erläutern. Was verbirgt sich hinter der Variablen $DIR? Ein echo $DIR liefert eine leere Ausgabe, aber eingebaut in find funktioniert es. Dirk
Hallo Dirk, ich:
for f in `find $DIR -regex ".*[äöüAÖÜ].*"` do mv $f `echo $f | sed -e"s/ä/ae/g" -e"s/ö/oe/g" -e"s/ü/ue/g" \ -e"s/Ä/Ae/g" -e"s/Ö/Oe/g" -e"s/Ü/Ue/g"` done
On Friday 15 October 2004 09:12, Dirk Meier wrote:
das ist eine schöne Lösung und funktioniert einwandfrei.
Leider ist bei der Ausführung ein weiteres Problem aufgetaucht. Es existieren auch Dateinamen, die Leerzeichen enthalten.
for f in `find $DIR -regex ".* .*"` do mv $f `echo $f | sed -e"s/ /_/g"` done
funktioniert nicht, da mv die Dateinamen mit Leerzeichen als mehrere Dateinamen interpretiert. Gibt es da auch eine einfache Lösung? ja, man muß Quoten und eine while-Schleife benutzen:
#-----------------------------|--- hier steht ein Blank! find $DIR -regex ".*[äöüÄÖÜ ] .*" | \ while read f do ff=`echo $f | sed -e"s/ä/ae/g" \ -e"s/ö/oe/g" \ -e"s/ü/ue/g" \ -e"s/Ä/Ae/g" \ -e"s/Ö/Oe/g" \ -e"s/Ü/Ue/g" \ -e"s/ /_/g"` mv "$f" "$ff" done Die while-Schleife muß man hier benutzen, da die for-Schleife ihre Argument am Blank trennt, so daß "a b" zu zwei Schleifendürchläufen führt einer für a und einer für b. Die while-Schleife hingegen list ihre Eingabe zeilenweise. Enthalten die Dateinamen nun auch noch \n (NewLine) dann wirds noch komplizierter, aber lassen wird das mal. Dirk:
Außerdem habe ich den ersten Teil mit set +x nicht verstanden. Kannst Du dass bitte erläutern.
ich:
ein set +x vor der Ausfühung des Kommandos gibt den Grund daf+ür an: ------ ++ echo '{}' ++ sed s/ä/ae/g + find . -name testä -exec echo mv -v '{}' '{}' ';' mv -v ./testä ./testä ------
set +x veranlasst die Shell auszugeben, wie sie Kommandos expandiert usw. Hier zeigte sich, daß das echo und sed Kommando vor find ausgeführt wurde (es steht ja vor find und ist mit zwei "+" versehen, das find nur mit einem. Das set +x ist für ein Hilfsmittel, komplexe Kommandos zu verstehen. Mehr dazu in "man bash". Dirk:
Was verbirgt sich hinter der Variablen $DIR? Ein echo $DIR liefert eine leere Ausgabe, aber eingebaut in find funktioniert es. Einfach nur: DIR ist eine Shell-Variable, welche das Verzeichnis angibt, das durchsucht werden soll. Zuweisung (wie in der shell üblich: DIR=/home/ichoderdu/irgendetwas oder eben dieses Verzeichnis direkt im find Kommando angeben.
Das das ohne Zuweisung an DIR in find funktioniert ist eine Besonderheit von find: wird kein Verzeichnis angegeben wird das aktuelle durchsucht. Da DIR nicht gestzt wurde, ist $DIR der leere String und dann.... Bye Jürgen PS: Für Shell-Anfänger (wie Du vermutlich (ohne Dir zu nahetreten zu wollen) einer bist), empfehle ich z.B. @BOOK{herold.1996a, AUTHOR = "Herold, Helmut", SERIES = "UNIX und seine Werkzeuge", TITLE = "Unix-Shells", PUBLISHER = addison, YEAR = 1996, EDITION = 2, KEYWORD = "Programmiersprachen, Bourne Shell, Korn-Shell, C-Shell, bash, tcsh", } Das gibt's inwzischen auch mit "Linux" im Titel in einer neuen Auflage. Eben alter Wein in neuen Schläuchen :-) -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 9204871 Fax: +49(721) 24874 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
Hallo, Am Fri, 15 Oct 2004, Dr. Jürgen Vollmer schrieb:
On Friday 15 October 2004 09:12, Dirk Meier wrote: [..]
funktioniert nicht, da mv die Dateinamen mit Leerzeichen als mehrere Dateinamen interpretiert. Gibt es da auch eine einfache Lösung? ja, man muß Quoten und eine while-Schleife benutzen:
#-----------------------------|--- hier steht ein Blank! find $DIR -regex ".*[äöüÄÖÜ ] .*" | \ while read f do ff=`echo $f | sed -e"s/ä/ae/g" \ ^! ^^!
-e"s/ö/oe/g" \ -e"s/ü/ue/g" \ -e"s/Ä/Ae/g" \ -e"s/Ö/Oe/g" \ -e"s/Ü/Ue/g" \ -e"s/ /_/g"`
^!
mv "$f" "$ff" done
$ ls -b test\ ä\ ö\ ü test*test testätest testäÄöÖüÜß Ääähem! Ääähem\? $ find . -name '*[^A-Za-z0-9]*' \ | while read f; do ff=`echo $f | sed -e 's/ä/ae/g;s/ö/oe/g;s/ü/ue/g;' \ -e 's/Ä/Ae/g;s/Ö/Oe/g;s/Ü/Ue/g;s/ß/ss/g;s/ /_/g'`; echo "»$f«" "»$ff«"; done »./testätest« »./testaetest« »./test*test« »./test*test_./testaetest« »./testäÄöÖüÜß« »./testaeAeoeOeueUess« »./Ääähem?« »./Aeaeaehem!_./Aeaeaehem?« »./test ä ö ü« »./test_ae_oe_ue« »./Ääähem!« »./Aeaeaehem!« Fällt dir in den Zeilen 2 und 4 was auf? Besser: $ find . -name '*[^A-Za-z0-9]*' \ | while read f; do \ ff="`echo \"$f\" | sed -e 's/ä/ae/g;s/ö/oe/g;s/ü/ue/g;' \ -e 's/Ä/Ae/g;s/Ö/Oe/g;s/Ü/Ue/g;s/ß/ss/g;s/ /_/g'`"; \ echo "»$f«" "»$ff«"; \ done »./testätest« »./testaetest« »./test*test« »./test*test« »./testäÄöÖüÜß« »./testaeAeoeOeueUess« »./Ääähem?« »./Aeaeaehem?« »./test ä ö ü« »./test_ae_oe_ue« »./Ääähem!« »./Aeaeaehem!« Der Unterschied? Das richtige quoten! ff="`echo \"$f\" | ...`" ^! ^^! ^^! ^! HTH, -dnh -- Wer eine Personal Firewall verwendet, könnte auch eine Einkaufstüte als Kondom benutzen: Den Sicherheits- und Lustgewinn beider Methoden halten wir für vergleichbar. ;-) [T-Online-Team in t-online.talk.internet]
On Friday 15 October 2004 22:10, David Haller wrote:
David Haller
$ ls -b test\ ä\ ö\ ü test*test testätest testäÄöÖüÜß Ääähem! Ääähem\?
ok, man muß aber auch die Aufgabenstellung betrachten: Umlaute und Blanks, von andren Sonderzeichen stand da nichts. Ich denke, man kann natürlich jedes Skipt für alle Eventualitäten wappnen, aber ist das sinnvoll? (Kann dieses Skript mit beliebig vielen also 100.000-den Dateien umgehen, oder was passiert wenn?, was wenn mittendrin der Strom ausfällt die Platte crashed, usw.usf) Ich denke es ist nicht sinnvoll für solche Kleinigkeiten alles zu bedenken. Der Vorteil von Skripten ist ja, daß eine kleine Aufgabe schnell erledigt werden kann. (Was anderes ist, wenn dies eine hochsicherheitsrelevant Aufgabe ist, bei dern Scheitern die Folgekosten sehr hoch wären, Kurz und gut man muß Kosten und Nutzen abwägen) bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 9204871 Fax: +49(721) 24874 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
Hallo, Am Sat, 16 Oct 2004, Dr. Jürgen Vollmer schrieb:
On Friday 15 October 2004 22:10, David Haller wrote: David Haller
$ ls -b test\ ä\ ö\ ü test*test testätest testäÄöÖüÜß Ääähem! Ääähem\?
ok, man muß aber auch die Aufgabenstellung betrachten: Umlaute und Blanks, von andren Sonderzeichen stand da nichts.
*gna* Nein, stand da nicht. Aber wenn man die _ALLEIN DURCH SAUBERES QUOTEN_ in den Griff bekommt... Wie war noch der "Schlauchschellen"-Dateiname bei Ratti? Gewöhne dir (als jemand der antwortet) bitte einfach an, sauber zu quoten! Das Muster variable="`echo \"$var\" | programm`" als funktioniert robuster als alle anderen Varianten. -dnh -- When I was a boy all our networks Were for hauling in fish from the sea-- Our bawd rate was eight bits an hour (and she was worth it!), And our IP address was just three. And you kids who complain that the World Wide Web Is too slow oughtta cut out your bitching, 'Cause when I was a boy every packet Was delivered by carrier pigeon. -- Frank Hayes
participants (3)
-
David Haller
-
Dirk Meier
-
Dr. Jürgen Vollmer