Hi Leute, kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann? Thanx & Cu Joachim MIld Email: joe@desastermail.de
Hallo, On Sun, 27 May 2001 at 14:13 +0200, Joachim Mild wrote:
kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann?
Dafür gibt's ziemlich viele Möglichkeiten. Z. B. alle Dateien im Verzeichnis (ein Verzeichnis ist auch eine Datei): for i in * ; do mv $i `echo $i | tr [[:lower:]] [[:upper:]]` ; done ^ ^ das sind Backticks und keine Hochkommata man tr man bash Gruß, Bernhard -- ----------------------------------------------------------------- -> http://www.links2linux.de <-> http://packman.links2linux.de <- ----------------------------------------------------------------- ******************** Gnu PGP-Key: DDAF6454 * Tux# 171705 * ICQ# 98361051
On Son, Mai 27, 2001 at 02:40:01 +0200, Bernhard Walle wrote:
On Sun, 27 May 2001 at 14:13 +0200, Joachim Mild wrote:
kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann?
Dafür gibt's ziemlich viele Möglichkeiten. Z. B. alle Dateien im Verzeichnis (ein Verzeichnis ist auch eine Datei):
for i in * ; do mv $i `echo $i | tr [[:lower:]] [[:upper:]]` ; done ^ ^ das sind Backticks und keine Hochkommata
Nebenbei: Was haben die doppelten [[ und ]] für einen Hintergrund? Das klappt doch auch mit einfachen [ und ], oder? Bei mir jedenfalls tut es das. Jedesmal wenn die Frage kommt (dürfte ca. 1x pro Monat sein - schau mal ins Archiv ;-), der gleiche Kommentar von mir: Die o. g. Kurzversion klappt nur dann sauber, wenn es in diesem Verzeichnis (bzw. allgemein gesprochen in der Auswahl der zu konvertierenden Dateien) keine Dateien gibt, die nur Kleinbuchstaben im Dateinamen haben! Wenn das nicht sicher ist, hagelt es Fehlermeldungen. Also lieber ein wenig mehr Aufwand: Variante 1: Keine Dateien in die Auswahl, die nur aus Kleinbuchstaben bestehen: for i in *[A-Z]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done Variante 2: Prüfen, ob der neue Dateiname gleich dem alten ist: for i in * ; do n=`echo $i | tr [:lower:] [:upper:]` test $n = $i || mv $i $n done Beide Varianten haben immer noch den Nachteil, dass es rappelt, wenn zufälligerweise eine Datei besteht, deren Dateiname dem umgewandelten einer Großbuchstabendatei *g* entspricht. Um sicher zu gehen, dass nichts überschrieben wird, kann man das kombinieren. Variante 3: for i in *[A-Z]* ; do n=`echo $i | tr [:lower:] [:upper:]` test -f $n && echo $n gibt es schon || mv $i $n done Die Variante unterscheidet sich in der Funktion zwar nicht von Bernhards Kurzfassung, aber man kann statt des echo ... ja auch eine andere Aktion einbauen (also z. B. einen neuen Dateinamen vergeben). Jan
On Sun, 27 May 2001 at 17:11 +0200, Jan Trippler wrote:
On Son, Mai 27, 2001 at 02:40:01 +0200, Bernhard Walle wrote:
On Sun, 27 May 2001 at 14:13 +0200, Joachim Mild wrote:
kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann?
Dafür gibt's ziemlich viele Möglichkeiten. Z. B. alle Dateien im Verzeichnis (ein Verzeichnis ist auch eine Datei):
for i in * ; do mv $i `echo $i | tr [[:lower:]] [[:upper:]]` ; done ^ ^ das sind Backticks und keine Hochkommata
Nebenbei: Was haben die doppelten [[ und ]] für einen Hintergrund? Das klappt doch auch mit einfachen [ und ], oder? Bei mir jedenfalls tut es das.
Hast recht, geht auch ohne. Halt der selbe Unterschied wie [a] und a, d. h. die inneren [] gehören zum Muster dazu. [[:upper:][:lower:]] =! [:upper:][:lower:]
Jedesmal wenn die Frage kommt (dürfte ca. 1x pro Monat sein - schau mal ins Archiv ;-), der gleiche Kommentar von mir:
Die o. g. Kurzversion klappt nur dann sauber, wenn es in diesem Verzeichnis (bzw. allgemein gesprochen in der Auswahl der zu konvertierenden Dateien) keine Dateien gibt, die nur Kleinbuchstaben im Dateinamen haben!
Wenn das nicht sicher ist, hagelt es Fehlermeldungen.
Schon, aber es geht trotzdem. An das habe ich aber gar nicht gedacht, da man meistens irgendwelche CD-ROMs hat, wo alles in Großbuchstaben vorliegt.
Also lieber ein wenig mehr Aufwand:
Variante 1: Keine Dateien in die Auswahl, die nur aus Kleinbuchstaben bestehen: for i in *[A-Z]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done
Diese Variante hat zwei Nachteile: Die Datei "äöü" wird nicht berücksichtigt und wenn in dem Verzeichnis überhaupt keine Dateien mit Großbuchstaben vorkommen, kommt Mist raus.
Variante 2: Prüfen, ob der neue Dateiname gleich dem alten ist: for i in * ; do n=`echo $i | tr [:lower:] [:upper:]` test $n = $i || mv $i $n done
Die Lösung ist optimal. Werde ich mir merken ;-)
Beide Varianten haben immer noch den Nachteil, dass es rappelt, wenn zufälligerweise eine Datei besteht, deren Dateiname dem umgewandelten einer Großbuchstabendatei *g* entspricht.
Dann könnte man "mv -i" nehmen, das fragt vor dem Überschreiben nach. Also: for i in * ; do n=`echo "$i" | tr [:ower:] [:upper]` [ "$n" = "$i" ] || mv -i "$i" "$n" done Um gleich Dateien mit Whitespaces zu berücksichtigen. Achja: Ob man nun test oder [] nimmt, ist Geschmackssache. test ist kompatbiler, [] sieht IMHO schöner aus ;-) Gruß, Bernhard -- Bitte die Etikette der Liste beachten. Diese enthält nützliche Regeln für den Umgang mit der Liste. http://home.t-online.de/~f.walle/etikette.html ******************** Gnu PGP-Key: DDAF6454 * Tux# 171705 * ICQ# 98361051
On Son, Mai 27, 2001 at 06:33:32 +0200, Bernhard Walle wrote:
On Sun, 27 May 2001 at 17:11 +0200, Jan Trippler wrote: [...]
Variante 1: Keine Dateien in die Auswahl, die nur aus Kleinbuchstaben bestehen: for i in *[A-Z]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done
Diese Variante hat zwei Nachteile: Die Datei "äöü" wird nicht berücksichtigt und wenn in dem Verzeichnis überhaupt keine Dateien mit Großbuchstaben vorkommen, kommt Mist raus.
Hattu Recht ;-) Kann man aber auch lösen (logo): Die Umlaute werden mit for i in *[A-ZÄÖÜ]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done erwischt und das 2. Problem besteht in _jeder_ Variante - nämlich immer dann, wenn keine zutreffende Datei gefunden wird. Das kann man mit einer kleinen Abfrage vorneweg klären: test -z "*[A-ZÄÖÜ]*" && exit 0 [...]
Beide Varianten haben immer noch den Nachteil, dass es rappelt, wenn zufälligerweise eine Datei besteht, deren Dateiname dem umgewandelten einer Großbuchstabendatei *g* entspricht.
Dann könnte man "mv -i" nehmen, das fragt vor dem Überschreiben nach. Also:
for i in * ; do n=`echo "$i" | tr [:ower:] [:upper]` [ "$n" = "$i" ] || mv -i "$i" "$n" done
Naja, das ist nicht ganz das Gleiche: -i setzt eine Interaktion voraus und kann nicht mehr in einem Batch-Job genutzt werden. Und wenn der Fall mehr als 10 mal eintritt, wird das Ganze zu einer ziemlich nervigen Angelegenheit ;-) Außerdem gibt es dann nur die Variante *friss oder stirb* sprich: Überschreibe oder lass es sein. Da ist es besser, wenn man ohne Benutzereingriff ein selbst definiertes Fallback einsetzen kann (und wenn es ein temporärer Dateiname a la tmp_kleiner_Dateiname ist).
Um gleich Dateien mit Whitespaces zu berücksichtigen.
ACK, hatte ich ignoriert.
Achja: Ob man nun test oder [] nimmt, ist Geschmackssache. test ist kompatbiler, [] sieht IMHO schöner aus ;-)
Ich weiss nicht, ob test kompatibler ist - ich habe noch kein *nix oder *nux getroffen, was die eckigen Klammern nicht kennt. Aber wie gesagt: Geschmackssache und ich finde test viel schicker ;-) BTW: Es hat schon einen handfesten Hintergrund - ich habe früher mal Schulungen u. a. im Bereich Shell gemacht und mit einem test vorneweg statt der [] drumrum wurde den Leuten immer viel schneller klar, dass dies ein eigenständiges Kommando ist. Die Klammern haben sie schnell mal als unwichtig weggelassen ;-) Außerdem: Die Sache mit den Leerzeichen. Es ist IMHO leichter zu sehen, wenn zwischen test und Argument eins fehlt, als bei den Klammern. Die Fehlermeldungen sind auch nicht gerade intuitiv und verwirren den Laien IMHO mehr als sie helfen: $ [-d . ] && echo ok bash: [-d: command not found $ [ -d .] && echo ok [: missing `]' $ [ -d . ] && echo ok ok $ Jan
Hallo, On Sun, 27 May 2001 at 19:58 +0200, Jan Trippler wrote:
On Son, Mai 27, 2001 at 06:33:32 +0200, Bernhard Walle wrote:
On Sun, 27 May 2001 at 17:11 +0200, Jan Trippler wrote: [...]
Variante 1: Keine Dateien in die Auswahl, die nur aus Kleinbuchstaben bestehen: for i in *[A-Z]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done
Diese Variante hat zwei Nachteile: Die Datei "äöü" wird nicht berücksichtigt und wenn in dem Verzeichnis überhaupt keine Dateien mit Großbuchstaben vorkommen, kommt Mist raus.
Hattu Recht ;-)
Kann man aber auch lösen (logo): Die Umlaute werden mit
for i in *[A-ZÄÖÜ]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done
erwischt
dann schauen die Franzosen mit ihren Akzenten aber wieder recht dumm. Mal abgesehen von der Tatsache, dass man solche Sachen in Dateinamen möglichst *nicht* verwenden sollte, kannst Du nicht den ganzen latin1-Zeichensatz da reinpacken ;-)
und das 2. Problem besteht in _jeder_ Variante - nämlich immer dann, wenn keine zutreffende Datei gefunden wird. Das kann man mit einer kleinen Abfrage vorneweg klären:
ACK.
test -z "*[A-ZÄÖÜ]*" && exit 0
Geht nicht. Gerade dann wird ja der String nicht ersetzt sondern bleibt stehen => String ist nicht Null => geht nicht. Siehe: berwal@hugo:~/t/t > ls berwal@hugo:~/t/t > test -z "*[A-ZÄÖÜ]*" && echo "test" berwal@hugo:~/t/t > Dafür geht folgendes: test -z "`ls`" && exit 0test -z "`ls`" && exit 0 Siehe: berwal@hugo:~/t/t > test -z "`ls`" && echo "test" test [Verzeichnis immer noch leer] Ich würde jetzt folgendes vorschlagen: ============================================================ #!/bin/sh # Überprüfen, ob leeres Verzeichnis if [ -z "`ls`" ] ; then echo "Das Verzeichnis ist leer." exit 0 fi # Schleife für jede Datei for file in * ; do # Neuer Name new=`echo "$file" | tr [:upper:] [:lower:]` # Überprüfen, ob Dateiname schon Kleinbuchstaben if [ "$new" = "$file" ] ; then echo "$file: Datei schon in Kleinbuchstaben." continue fi # wenn Großbuchstaben umgewandelt in Kleinbuchstaben eine Datei # ergeben, die schon existiert [ -f "$new" -o -d "$new" ] && new="${new}_" # Endlich umbenennen mv "$file" "$new" done ============================================================ Da müsste eigentlich alles drin sein.
$ [-d . ] && echo ok bash: [-d: command not found $ [ -d .] && echo ok [: missing `]' $ [ -d . ] && echo ok ok $
Mir gefallen die Klammern trotzdem besser ;-) Gruß, Bernhard -- Du suchst was zum Thema Linux? Hier findest Du garantiert was: http://www.links2linux.de ******************** Gnu PGP-Key: DDAF6454 * Tux# 171705 * ICQ# 98361051
On Son, Mai 27, 2001 at 09:13:23 +0200, Bernhard Walle wrote:
On Sun, 27 May 2001 at 19:58 +0200, Jan Trippler wrote: [...]
Die Umlaute werden mit
for i in *[A-ZÄÖÜ]* ; do mv $i `echo $i | tr [:lower:] [:upper:]` ; done
erwischt
dann schauen die Franzosen mit ihren Akzenten aber wieder recht dumm. Mal abgesehen von der Tatsache, dass man solche Sachen in Dateinamen möglichst *nicht* verwenden sollte, kannst Du nicht den ganzen latin1-Zeichensatz da reinpacken ;-)
Warum nicht? Das ist nur eine endliche Anzahl von Zeichen ;-) Nur aus Jux: Ich will natürlich nicht das ganze Geraffel aingeben, wozu haben wir denn die Shell! pattern=A-Z for i in `seq 161 255`; do oct=`printf "%c%03o" "\\\" $i` pattern=$pattern`echo -e "$oct"` done Dann ein gemütliches for i in *[$pattern]*; do ...
test -z "*[A-ZÄÖÜ]*" && exit 0
Geht nicht. Gerade dann wird ja der String nicht ersetzt sondern bleibt stehen => String ist nicht Null => geht nicht. Siehe:
Stimmt, ich hatte nur den Positivfall getestet. :-(
berwal@hugo:~/t/t > ls berwal@hugo:~/t/t > test -z "*[A-ZÄÖÜ]*" && echo "test" berwal@hugo:~/t/t >
Dafür geht folgendes:
test -z "`ls`" && exit 0test -z "`ls`" && exit 0
Du meinst: test -z "`ls`" && exit 0 (Deins kam doppelt an) Dann ist es aber einfacher, den ls direkt abzufragen: ls >/dev/null 2>&1 || exit 0 Das funktioniert aber nur, wenn der ls nicht mehrere Argumente kriegt und wenigstens eins davon finden soll. Er liefert nämlich immer 1, wenn er auf irgendein Argument hin keine Datei findet. Ah, gerade noch rechtzeitig eingefallen: test "*[A-ZÄÖÜ]*" = '*[A-ZÄÖÜ]*' && exit 0 weil nämlich in einfachen Quotes keine Substitution erfolgt. Jetzt gibt es nur noch Ärger, wenn es eine Datei gibt, die so wie das Suchmuster heisst - aber derjenige hat dann selber Schuld ;-) [test vs. []]
Mir gefallen die Klammern trotzdem besser ;-)
Denk doch nur mal an die Gefahren, die durch Verwechslung mit den von uns oben im ls oder tr genutzten Suchmustern oder in regulären Ausdrücken entstehen ;-) Heillose Verwirrung! Anarchie! Der Untergang des Abendlandes! Jan
On Sunday, 27. May 2001 14:40, Bernhard Walle wrote:
On Sun, 27 May 2001 at 14:13 +0200, Joachim Mild wrote:
kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann?
Dafür gibt's ziemlich viele Möglichkeiten. Z. B. alle Dateien im Verzeichnis (ein Verzeichnis ist auch eine Datei):
for i in *; do mv $i `echo $i | tr [[:lower:]] [[:upper:]]`; done
Als kleine Ergänzung: Wenn die $i zu "$i" werden, funktioniert das auch mit Dateinamen, die Leerzeichen enthalten. Gruß, Stephan -- Stephan Hakuli | mailto: stephan@hakuli.de | * GnuPG/PGP-Key * | callto: 01 71 - 651 89 43 | available, please | surfto: http://www.hakuli.de | visit my homepage
On Son, 27 Mai 2001, Joachim Mild wrote:
kann mir einer sagen wie Dateien und Verzeichnisse die in Großbuchstaben geschrieben sind, in Kleinbuchstaben umwandeln kann?
Wenn's keine Kollisionen mit vorhandenen Dateien geben kann (mit dem -p sollte es aber auch dann gehen): mmv -p "*" "#l1" Siehe man mmv. -dnh -- 105: Wassenaar The real aim of current policy is to ensure the continued effectiveness of US information warfare assets against individuals, businesses and governments in Europe and elsewhere" (Ross Anderson)
participants (5)
-
Bernhard Walle
-
David Haller
-
Jan.Trippler@t-online.de
-
Joachim Mild
-
Stephan Hakuli