Scriptfrage: Zahlen+Sonderzeichen am Dateinamensanfang löschen
Hallo, ich habe schon relativ viel herumprobiert, um mit einer for-Schleife und sed und mv die Dateinamen aus meinem Musik-Ordner so umzubenennen, dass ich die Zahlen und Sonderzeichen (hauptsächlich . und - und _ und [ ] (Leerzeichen)). Diese komischen Dateinamen haben sich irgendwie durch das Rippen von Musik-CDs ergeben, da jedes Rip-Programm irgendwie eine andere Syntax verwendet.. Am Anfang steht also eine beliebige Anzahl von Zahlen+evtl obige Zeichen. Dann folgen normale Buchstaben. Und dieses "beliebige Anzahl" habe ich nicht hinbekommen. Ich bin etwa bis: for i in "1*" ; do mv -iv "$i" `sed -e 's/.\(.*\)/\1/'` ; done gekommen... Bei der sed-Syntax bin ich mir nicht ganz sicher, da ich da gegooglet habe und das sed -e 's/.\(.*\)/\1/ da als Beispiel für ein sedscript stand... Durch die englische Manpage von sed und bash steige ich nicht durch... Mit mmv "1*" "#1" geht das auch. Aber ich will ja wie gesagt, dass eine beliebige Anzahl von Ziffern und evtl . oder _ oder - oder [ ] (Leerzeichen) entfernt wird... Eine letzte Möglichkeit, die ich noch gefunden habe, ist dieses ##1, wobei das für mich auch total neu ist... for i in 1*; do mv $i; ${i##1};done Aber bei dem Problem mit der beliebigen Anzahl und beliebiger Verteilung von bestimmten Zeichen hat mir das auch nicht geholfen... Kann mir da bitte jemand helfen? Für jegliche Tips und Anregungen bin ich dankbar Gruß Sören
Hallo, Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Ich bin etwa bis:
for i in "1*" ; do mv -iv "$i" `sed -e 's/.\(.*\)/\1/'` ; done ^ wird nicht expandiert, da gequoted.
Ausserdem gibst du sed keine Eingabe. Wobei das z.B. _jedes_ erste Zeichen loescht, also auch normale Buchstaben. Besser ist, du invertierst die Bedingung: alles vor dem ersten Buchstaben loeschen. for oldname in [^a-zA-Z]*; do newname="`echo \"$f\" | sed 's/^[^a-zA-Z]*\([a-zA-Z].*\)/\1/'`" if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v "$oldname" "$newname" fi done HTH, -dnh -- Ich glaube aber nicht, dass der DDR Ram hat. Er hat seinen Rechner doch erst vor einem Jahr gekauft! Die werden Ihm da doch nicht uralt-Speicherbausteine hereingesteckt haben. Maximal kann er also "Ex-DDR"-Speicher haben (Sprich Infineon, denn die Produzieren ja auch in Dresden ...). -- Konrad Neitzel
Hallo, Am Samstag, 20. November 2004 19:43 schrieb David Haller:
Hallo,
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Ich bin etwa bis:
for i in "1*" ; do mv -iv "$i" `sed -e 's/.\(.*\)/\1/'` ; done
^ wird nicht expandiert, da gequoted. OK
Ausserdem gibst du sed keine Eingabe. Wobei das z.B. _jedes_ erste Zeichen loescht, also auch normale Buchstaben. Naja.. daher ja das 1*.. aber da hat ja mein Quoting die Expansion verhindert.
Besser ist, du invertierst die Bedingung: alles vor dem ersten Buchstaben loeschen. Gute Idee.
for oldname in [^a-zA-Z]*; do newname="`echo \"$f\" | sed 's/^[^a-zA-Z]*\([a-zA-Z].*\)/\1/'`" if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v "$oldname" "$newname" fi done Vielen Dank für deine Mühe.
Ich habe mal hier vor ein paar Dateien ein paar Zahlen gesetzt. Aber leider funktioniert das irgendwie nicht (mache ich irgendwas falsch?) ,,13692-penguins_big.jpg" -> ,," mv: Verschieben von ,,13692-penguins_big.jpg" nach ,," nicht möglich: Datei oder Verzeichnis nicht gefunden So, wie ich das sehe, ist irgendwie ein Fehler in dem Teil mit sed, oder? Jedenfalls scheint die Variable $newname irgendwie leer zu sein, soweit ich das beurteilen kann. vielen Dank Gruß Sören
Hallo, Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller:
Besser ist, du invertierst die Bedingung: alles vor dem ersten Buchstaben loeschen. Gute Idee.
for oldname in [^a-zA-Z]*; do newname="`echo \"$f\" | sed 's/^[^a-zA-Z]*\([a-zA-Z].*\)/\1/'`" ^^^^^^ *ARGH*
Ich verwende normalerweise fuer Dateien 'f', also 'for f in'. Da muss hier natuerlich 'echo \"$oldname\"' hin. [..]
So, wie ich das sehe, ist irgendwie ein Fehler in dem Teil mit sed, oder? Jedenfalls scheint die Variable $newname irgendwie leer zu sein, soweit ich das beurteilen kann.
Jep. s.o. Folgendes muesste klappen: ==== for oldname in [^a-zA-ZäöüßÄÖÜ]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v "$oldname" "$newname"; fi; done ==== Ggfs. musst du in die [] noch weitere Zeichen aufnehmen. Wobei die beim 'for' egal ist (das faengt der Vergleich oldname/newname ab), da reicht also prinzipiell auch ein 'for oldname in *; do'. Sorry wg. dem Fehler. Ich sollte wohl doch erst testen ;) -dnh --
Mag sein, ändert aber nichts am instinktiven Verhalten. Auf alle Fälle kramen Frauen gerne irgendwo rum, wenn sie Autofahren... :) -- J. Lippert Deshalb sind der Spiegel in der Sonnenblende und das Handschuhfach stets rechts eingebaut. -- R. Schwentker
Hallo, und gleich mal vielen vielen Dank für dein tolles Script! Am Samstag, 20. November 2004 22:06 schrieb David Haller:
Hallo,
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller: [..]
Besser ist, du invertierst die Bedingung: alles vor dem ersten Buchstaben loeschen.
Gute Idee.
[Skript1]
Ich verwende normalerweise fuer Dateien 'f', also 'for f in'. Da muss hier natuerlich 'echo \"$oldname\"' hin. Juhu, jetzt funktionierts :-)
soeren@linux:~/temp> sh script ,,13692-penguins_big.jpg" -> ,,penguins_big.jpg" Was ich aber nicht verstehe ist folgendes: soeren@linux:~/temp> touch _-_-_-_test soeren@linux:~/temp> sh script soeren@linux:~/temp> ls *test _-_-_-_test soeren@linux:~/temp> Aber: soeren@linux:~/temp> sh script ,,_-test" -> ,,test" soeren@linux:~/temp> Naja... und mv kann das auch. Du brauchst nichts mehr am Script zu ändern (dieses _-_-_-_ wirds wohl kaum am Anfang einer Sounddatei geben ;-). Würde mich nur mal Interessieren, woran das liegt.
[..]
So, wie ich das sehe, ist irgendwie ein Fehler in dem Teil mit sed, oder? Jedenfalls scheint die Variable $newname irgendwie leer zu sein, soweit ich das beurteilen kann.
Jep. s.o. Folgendes muesste klappen:
==== for oldname in [^a-zA-ZäöüßÄÖÜ]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v "$oldname" "$newname"; fi; done ====
Ggfs. musst du in die [] noch weitere Zeichen aufnehmen. Wobei die beim 'for' egal ist (das faengt der Vergleich oldname/newname ab), da reicht also prinzipiell auch ein 'for oldname in *; do'. Ok.
Sorry wg. dem Fehler. Ich sollte wohl doch erst testen ;) Kein Problem :-)
Gruß Sören
Hallo, Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 22:06 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller: [..]
Besser ist, du invertierst die Bedingung: alles vor dem ersten Buchstaben loeschen.
Gute Idee.
[Skript1]
Ich verwende normalerweise fuer Dateien 'f', also 'for f in'. Da muss hier natuerlich 'echo \"$oldname\"' hin. Juhu, jetzt funktionierts :-)
soeren@linux:~/temp> sh script ,,13692-penguins_big.jpg" -> ,,penguins_big.jpg"
Aeh, verwendest du ,, und " um die Dateinamen zu kennzeichnen? Halte ich nicht fuer guenstig. ich nehm da entweder ' und ' oder » und «. Oder gerade bei sowas garnix.
Was ich aber nicht verstehe ist folgendes:
soeren@linux:~/temp> touch _-_-_-_test soeren@linux:~/temp> sh script soeren@linux:~/temp> ls *test _-_-_-_test soeren@linux:~/temp>
Aber: soeren@linux:~/temp> sh script ,,_-test" -> ,,test" soeren@linux:~/temp>
Kann ich nicht nachvollziehen: $ for oldname in [^A-Za-z]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then echo "$oldname -> $newname"; else echo "not moving '$oldname'"; fi; done ,,_-_-_-_test -> test ,,_-_-_-_test" -> test" --foo" -> foo" _-_-_-_test -> test (die "not moving ..." hab ich hier jetzt mal weggelassen). Ups, noch ein Bug: $ for oldname in [^A-Za-z]*; do newname="`echo \"$oldname\" | sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v "$oldname" "$newname"; else echo "not moving '$oldname'"; fi; done ,,_-_-_-_test -> test ,,_-_-_-_test" -> test" mv: Unbekannte Option »--foo"« Versuchen Sie »mv --help« für weitere Informationen. Also verwende: ==== for oldname in [^A-Za-z]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v -- "$oldname" "$newname" else echo "not moving '$oldname'"; fi; done ==== Bei mir funktioniert das. Ansonsten zeig mal den Ablauf mit "sh -x" -dnh -- Einen kurzen Abschnitt aus einem Buch auf einen Zettel abschreiben: Mit dem Zeigefinger der rechten Hand über den Textabschnitt fahren, mit dem Mittel- finger auf das leere Papierblatt klopfen... BTDT, mehrmals. -- A. Grolms
Hallo, Am Sonntag, 21. November 2004 01:05 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 22:06 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller: [..] soeren@linux:~/temp> sh script ,,13692-penguins_big.jpg" -> ,,penguins_big.jpg"
Aeh, verwendest du ,, und " um die Dateinamen zu kennzeichnen? Ja.. wo kann man das denn ändern? In der ~/.bashrc?
Halte ich nicht fuer guenstig. ich nehm da entweder ' und ' oder » und «. Oder gerade bei sowas garnix. Warum ist ,, und " ungünstig?
Was ich aber nicht verstehe ist folgendes: [Beispiel] Kann ich nicht nachvollziehen: [Beispiel]
Also verwende:
==== for oldname in [^A-Za-z]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v -- "$oldname" "$newname" else echo "not moving '$oldname'"; fi; done ====
Bei mir funktioniert das. Ansonsten zeig mal den Ablauf mit "sh -x" Also bei mir funktioniert es jetzt auch. Der Fehler war wohl, dass ich da schon mehrere Dateien hatte, die nachher "test" heißen sollten. Das überprüft das Script wohl mit "if test "x${newname}" != "x${oldname}" && test ! -e "$newname";.." Das hatte ich gestern nicht bemerkt.
Jedenfalls funktioniert es ja jetzt. Hier nochmal die Ausgabe von sh -x. Deswegen ist mir das mit test -e auch erst aufgefallen. soeren@linux:~/temp/script-test> sh -x sh-2.05b$ ls + ls _-_-_-_test _-_-_-_-_test sh-2.05b$ for oldname in [^A-Za-z]*; do
newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e
"$newname";
then mv -v -- "$oldname" "$newname" else echo "not moving '$oldname'"; fi; done
++ echo _-_-_-_test ++ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/' + newname=test + test xtest '!=' x_-_-_-_test + test '!' -e test + mv -v -- _-_-_-_test test ,,_-_-_-_test" -> ,,test" ++ echo _-_-_-_-_test ++ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/' + newname=test + test xtest '!=' x_-_-_-_-_test + test '!' -e test + echo 'not moving '\''_-_-_-_-_test'\''' not moving '_-_-_-_-_test' sh-2.05b$ ls + ls test _-_-_-_-_test sh-2.05b$ rm test + rm test sh-2.05b$ for oldname in [^A-Za-z]*; do newname="`echo \"$oldname\" | \ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/'`"; if test "x${newname}" != "x${oldname}" && test ! -e "$newname"; then mv -v -- "$oldname" "$newname"; else echo "not moving '$oldname'"; fi; done ++ echo _-_-_-_-_test ++ sed 's/^[^a-zA-ZäöüßÄÖÜ]*\([a-zA-ZäöüßÄÖÜ].*\)/\1/' + newname=test + test xtest '!=' x_-_-_-_-_test + test '!' -e test + mv -v -- _-_-_-_-_test test ,,_-_-_-_-_test" -> ,,test" sh-2.05b$ ls + ls test Vielen Dank Gruß Sören PS: ich habe gestern schon fast 400 Dateien in ein ordentliches Format gebracht :-)
Hallo, Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb:
Am Sonntag, 21. November 2004 01:05 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 22:06 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller: [..] soeren@linux:~/temp> sh script ,,13692-penguins_big.jpg" -> ,,penguins_big.jpg"
Aeh, verwendest du ,, und " um die Dateinamen zu kennzeichnen? Ja.. wo kann man das denn ändern? In der ~/.bashrc?
Vergiss es, ich dachte, das waere von dir ein "echo". Ich verwende 'mv -v' so selten ;)
Also bei mir funktioniert es jetzt auch. Der Fehler war wohl, dass ich da schon mehrere Dateien hatte, die nachher "test" heißen sollten. Das überprüft das Script wohl mit "if test "x${newname}" != "x${oldname}" && test ! -e "$newname";.."
Genau. -dnh -- Kölsch ist kein Element der Menge Bier. Selbst wenn es nach 1000 Reinheitsge- boten gebraut wäre. -- Ein Glas Wasser entspricht strenggenommen auch dem Reinheitsgebot. Es ist dennoch nicht als Bier zu bezeichnen. Was weder die Amerikaner noch die Koelner zu stoeren scheint. -- J. P. Meier
Hallo, Am Sonntag, 21. November 2004 16:11 schrieb David Haller:
Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb:
Am Sonntag, 21. November 2004 01:05 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 22:06 schrieb David Haller:
Am Sat, 20 Nov 2004, Sören Wengerowsky schrieb:
Am Samstag, 20. November 2004 19:43 schrieb David Haller:
[..]
soeren@linux:~/temp> sh script ,,13692-penguins_big.jpg" -> ,,penguins_big.jpg"
Aeh, verwendest du ,, und " um die Dateinamen zu kennzeichnen?
Ja.. wo kann man das denn ändern? In der ~/.bashrc?
Vergiss es, ich dachte, das waere von dir ein "echo". Ich verwende 'mv -v' so selten ;) Ok
Also bei mir funktioniert es jetzt auch. Der Fehler war wohl, dass ich da schon mehrere Dateien hatte, die nachher "test" heißen sollten. Das überprüft das Script wohl mit "if test "x${newname}" != "x${oldname}" && test ! -e "$newname";.."
Genau.
Dann noch ein abschließendes Dankeschön für das schöne Script! Das hat mir wohl viele Stunden Arbeit erspart. Gruß Sören
Hallo, Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb:
Am Sonntag, 21. November 2004 16:11 schrieb David Haller:
Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb: [..]
Der Fehler war wohl, dass ich da schon mehrere Dateien hatte, die nachher "test" heißen sollten. Das überprüft das Script wohl mit "if test "x${newname}" != "x${oldname}" && test ! -e "$newname";.."
Genau.
Mist. Hier hatte ich noch vergessen: "Deswegen auch 'mv -v' und nicht 'mv -v -i'." Ohne den test und ohne das -i wuerde einem 'mv' eben bei Namenskollisionen die Dateien ueberschreiben. Und da ein 'mv -i' den script-Ablauf bei Kollisionen v.a. nur bremst hab ich den Test eben eingebaut. Was dann noch uebrigbleibt muss man halt "per Hand" umbenennen, dazu kann man ggfs. die Ausgabe im else-Zweig des Tests noch anpassen, z.B. so: else echo "kept $oldname" >&2 fi und dann das script mit ' 2>./__not_moved' o.ae. aufrufen und anschliessend die Fehlerausgabe per cut -d' ' -f2- < ./.__not_moved | while read f; do ... weiterverarbeiten.
Dann noch ein abschließendes Dankeschön für das schöne Script! Das hat mir wohl viele Stunden Arbeit erspart.
Bitte. -- In the middle of evil there's allways *vi* -- snarfed from "Sensor"
Hallo, Am Montag, 22. November 2004 03:39 schrieb David Haller:
Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb:
Am Sonntag, 21. November 2004 16:11 schrieb David Haller:
Am Sun, 21 Nov 2004, Sören Wengerowsky schrieb:
[..]
Der Fehler war wohl, dass ich da schon mehrere Dateien hatte, die nachher "test" heißen sollten. Das überprüft das Script wohl mit "if test "x${newname}" != "x${oldname}" && test ! -e "$newname";.."
Genau.
Mist. Hier hatte ich noch vergessen:
"Deswegen auch 'mv -v' und nicht 'mv -v -i'." ok
Ohne den test und ohne das -i wuerde einem 'mv' eben bei Namenskollisionen die Dateien ueberschreiben. Und da ein 'mv -i' den script-Ablauf bei Kollisionen v.a. nur bremst hab ich den Test eben eingebaut. Was dann noch uebrigbleibt muss man halt "per Hand" umbenennen, dazu kann man ggfs. die Ausgabe im else-Zweig des Tests noch anpassen, z.B. so:
else echo "kept $oldname" >&2 fi
Danke. Naja.. ich hatte jetzt noch nach "not moving" gegreppt... aber das ist natürlich eleganter..
und dann das script mit ' 2>./__not_moved' o.ae. aufrufen und anschliessend die Fehlerausgabe per
cut -d' ' -f2- < ./.__not_moved | while read f; do ...
weiterverarbeiten.
ok..
Danke nochmal Gruß Sören
participants (2)
-
David Haller
-
Sören Wengerowsky