Shell-Programmierung / echo / Leerzeichen -> Zeilenumbruch
Hallo Liste, hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript: #! /bin/sh for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was auch immer flasch gesetzt. Wer weiss Rat? Viele Grüsse Joachim
Am Donnerstag, 22. April 2004 19:06 schrieb Joachim Kieferle:
hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript:
#! /bin/sh
for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done
Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was
Nein, der echo ist nicht schuld, sondern die for-Schleife - da werden aus "Datei mit Leerzeichen" drei I ("Datei", "mit", "Leerzeichen"). Dafür gibt es mehrere Lösungen, z. B.: Vor die Schleife: OLDFS="$IFS" IFS=" " Damit setzt Du den "Input Field Separator" auf \n um, standardmäßig gehören auch White-Space-Zeichen dazu. Oder: find . -type f -name '*.JPG' -print | while read I; do mv "$I" "`echo $I | sed 's/.JPG/.jpg/'`" done BTW: Den sed kannst Du durch basename ersetzen, spart ne Pipe ein: mv "$I" "`basename \"$I\" .JPG`.jpg" Achte auf die von mir gesetzten Quotings! Jan
Jan Trippler wrote:
Am Donnerstag, 22. April 2004 19:06 schrieb Joachim Kieferle:
hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript:
#! /bin/sh
for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done
Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was
Nein, der echo ist nicht schuld, sondern die for-Schleife - da werden aus "Datei mit Leerzeichen" drei I ("Datei", "mit", "Leerzeichen"). Dafür gibt es mehrere Lösungen, z. B.:
Vor die Schleife: OLDFS="$IFS" IFS=" "
Damit setzt Du den "Input Field Separator" auf \n um, standardmäßig gehören auch White-Space-Zeichen dazu.
Oder: find . -type f -name '*.JPG' -print | while read I; do mv "$I" "`echo $I | sed 's/.JPG/.jpg/'`" done
Hallo Jan T. und Jan R., vielen Dank für Eure Tips. Da ich nicht nur Dateien umbenennen möchte, sondern ähnliche Schleifen auch noch für andere Dinge verwende (z.B. um in einem Verzeichnis mit Unterverzeichnissen tif- und jpg-Dateien runterzurechnen) und dann anschliessend mit "album" ein Webalbum zusammen zu stellen, ist die oben aufgezeigte Lösung für mich die praktikabelste. Funktioniert auch schon einwandfrei, Rechner konvertiert gerade 4 GB Bilder. Viele Grüsse Joachim
Hallo, Am Thu, 22 Apr 2004, Jan Trippler schrieb:
find . -type f -name '*.JPG' -print | while read I; do mv "$I" "`echo $I | sed 's/.JPG/.jpg/'`" done
BTW: Den sed kannst Du durch basename ersetzen, spart ne Pipe ein: mv "$I" "`basename \"$I\" .JPG`.jpg"
Die Loesung mit der bash kam ja auch schon. Aber wie waere's mit: find . -type d -print | while read dir; do pushd "$dir" mmv '*.JPG' '#1.jpg' popd done -dnh -- If you haven't got time to RTFM, you haven't got time to whine on this mailing list.
Hallo, Joachim Kieferle wrote:
hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript:
#! /bin/sh
for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done
Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was auch immer flasch gesetzt.
#!/bin/sh for I in `find . -type f -name '*.JPG'` do J = `echo "$I" | sed 's/.JPG/.jpg/'` mv "$I" "$J" done könne vielleicht hinhauen. Alternativ ' statt " probieren. Damian 'zu faul schon wieder den Shell-Guide zu wälzen' Philipp
Damian Philipp wrote:
Hallo,
Joachim Kieferle wrote:
hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript:
#! /bin/sh
for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done
Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was auch immer flasch gesetzt.
#!/bin/sh for I in `find . -type f -name '*.JPG'` do J = `echo "$I" | sed 's/.JPG/.jpg/'` mv "$I" "$J" done
Hallo Damian, vielen Dank, aber das funktioniert leider auch nicht. Das Problem liegt bei "echo", das die neue Zeile verursacht. Viele Grüsse Joachim
Am Donnerstag, 22. April 2004 19:34 schrieb Joachim Kieferle:
Damian Philipp wrote: [...]
#!/bin/sh for I in `find . -type f -name '*.JPG'` ^^^ _Das_ verursacht den Fehler do J = `echo "$I" | sed 's/.JPG/.jpg/'` ^^^ Fehler. Hier dürfen keine Leerzeichen hin. mv "$I" "$J" done
Hallo Damian,
vielen Dank, aber das funktioniert leider auch nicht. Das Problem liegt bei "echo", das die neue Zeile verursacht.
Nein, da liegt das Problem eben nicht - siehe meine andere Mail. Jan
Joachim Kieferle, Donnerstag, 22. April 2004 19:06:
Hallo Liste,
hänge mal wieder an einem Problem und komme einfach nicht weiter. Um in einem Verzeichnis rekursiv Dateien umzubenennen, habe ich folgendes Shell-Skript:
#! /bin/sh
for I in `find . -type f -name '*.JPG' `; do mv $I "`echo $I | sed 's/.JPG/.jpg/'`"; done
Allerdings funktioniert das nur bei Verzeichnissen _ohne_ Leerzeichen, weil "echo $I" statt des Leerzeichens einen Zeilenumbruch ausgibt. Bestimmt habe ich nur ein ", `, ' oder was auch immer flasch gesetzt.
Wer weiss Rat?
Warum so kompliziert, wenn es wirklich nur um die Änderung des Datei-Suffixes geht? Mit basename <datei> .JPG wird der Dateiname ohne Suffix ausgegeben. Da hängst du dann einfach die Zeichenkette".jpg" wieder ran: mv "$I" "`dirname $I`/`basename $I .JPG`.jpg" -- Gruß MaxX 8-) Hinweis 1: PMs an diese Adresse werden automatisch vernichtet. Hinweis 2: Bitte unbedingt beachten: http://www.suse-etikette.de.vu
Matthias Houdek wrote:
[...] Warum so kompliziert, wenn es wirklich nur um die Änderung des Datei-Suffixes geht?
Mit basename <datei> .JPG wird der Dateiname ohne Suffix ausgegeben. Da hängst du dann einfach die Zeichenkette".jpg" wieder ran:
mv "$I" "`dirname $I`/`basename $I .JPG`.jpg"
Warum so kompliziert, wenn es wirklich nur um die Aenderung des Datei-Suffixes geht? :-) --> mv "$I" "${I/\.JPG/.jpg}" Das ist allerdings bash-spezifisch. Ferner loest ein einfaches mv wie von Dir hier vorgeschlagen natuerlich nicht das eigentliche Problem mit der for-Schleife und Leerzeichen in Namen; siehe dazu die Mail von Jan. Ein "-i" als Option wuerde dabei sicher dann auch noch gut tun, um versehentliches Ueberschreiben einer evtl. bereits vorhandenen Datei abzufangen. CU, Th.
Thomas Hertweck wrote:
Matthias Houdek wrote:
[...] Warum so kompliziert, wenn es wirklich nur um die Änderung des Datei-Suffixes geht?
Mit basename <datei> .JPG wird der Dateiname ohne Suffix ausgegeben. Da hängst du dann einfach die Zeichenkette".jpg" wieder ran:
mv "$I" "`dirname $I`/`basename $I .JPG`.jpg"
Warum so kompliziert, wenn es wirklich nur um die Aenderung des Datei-Suffixes geht? :-)
--> mv "$I" "${I/\.JPG/.jpg}"
Das ist allerdings bash-spezifisch. Ferner loest ein einfaches mv wie von Dir hier vorgeschlagen natuerlich nicht das eigentliche Problem mit der for-Schleife und Leerzeichen in Namen; siehe dazu die Mail von Jan. Ein "-i" als Option wuerde dabei sicher dann auch noch gut tun, um versehentliches Ueberschreiben einer evtl. bereits vorhandenen Datei abzufangen.
CU, Th.
sorry mal nur ein kleiner schnellschuss, aber man kann den "IFS" der Bash ja auch einfach umschalten. Standardmässig steht der auf " " sprich, die for schleife behandelt den wert nach einer iteration als neuen Wert. Wenn Du den IFS z.b. auf ";2 setzt, dann haste die Probleme nicht. Falls ich daneben geschossen hab, sorry :) gruss, Christian
participants (7)
-
Christian Augustat
-
Damian Philipp
-
David Haller
-
Jan.Trippler@t-online.de
-
Joachim Kieferle
-
Matthias Houdek
-
Thomas Hertweck