bash: find mit sort - Re: [opensuse-multimedia-de] Eine ganze Festplatte mit mp3-Dateien...
Am Samstag, 6. Februar 2010 20:24:20 schrieb David Haller:
Das zerbröselt's. for .. in `` oder $() ist _IMMER_ schlecht.
find "$DIR" -type f -iname '*.mp3' -exec /bin/bash -c 'for file; do lame ... "$file" "${file//.mp3}_128.mp3" done' find-bash '{}' '+'
Ich frage mich gerade wie ich folgendes ohne for hinkriege. Es geht zB darum, dass ein Skript alle gefundenen Dateien alfabetisch sortiert und diese dann durchnummeriert und als Dateinamen den Ordnernamen verwendet. Grundsätzlich wäre es mir mit for klar, aber mit Davids Konstruktion komme ich nicht weiter. Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Sam, 13 Feb 2010, Al Bogner schrieb:
Am Samstag, 6. Februar 2010 20:24:20 schrieb David Haller:
Das zerbröselt's. for .. in `` oder $() ist _IMMER_ schlecht.
find "$DIR" -type f -iname '*.mp3' -exec /bin/bash -c 'for file; do lame ... "$file" "${file//.mp3}_128.mp3" done' find-bash '{}' '+'
Ich frage mich gerade wie ich folgendes ohne for hinkriege. Es geht zB darum, dass ein Skript alle gefundenen Dateien alfabetisch sortiert und diese dann durchnummeriert und als Dateinamen den Ordnernamen verwendet. Grundsätzlich wäre es mir mit for klar, aber mit Davids Konstruktion komme ich nicht weiter.
if test "x${DIR}" = "x." || test -z "$DIR"; then DIR="$PWD"; fi find "${DIR}" -type d | while read d; do pushd "$d"; i=0; for f in *.mp3; do test -d "$f" && continue; echo mv -i "$f" "${d##*\/}_$(printf "%05i.mp3" $i)"; i=$((i+1)); done; popd; done Wenn du anders sortieren willst als es die Shell bei * macht, dann mußt du z.B. i=0; find .. | sort .. | while read -r file; do ..; done; i=$((i+1) oder sowas verwenden. HTH, -dnh --
Ich habe das ausprobiert, aber wenn ich das auf yes stelle dann stürzt der PC beim Booten ab. Was Nun? Dann stell es am besten wieder auf "no". -- Betrefflose Frage und Antwort in suse-linux -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Sonntag, 14. Februar 2010 03:25:53 schrieb David Haller: Hallo David,
Am Sam, 13 Feb 2010, Al Bogner schrieb:
Am Samstag, 6. Februar 2010 20:24:20 schrieb David Haller:
Das zerbröselt's. for .. in `` oder $() ist _IMMER_ schlecht.
find "$DIR" -type f -iname '*.mp3' -exec /bin/bash -c 'for file; do lame ... "$file" "${file//.mp3}_128.mp3" done' find-bash '{}' '+'
Ich frage mich gerade wie ich folgendes ohne for hinkriege. Es geht zB darum, dass ein Skript alle gefundenen Dateien alfabetisch sortiert und diese dann durchnummeriert und als Dateinamen den Ordnernamen verwendet. Grundsätzlich wäre es mir mit for klar, aber mit Davids Konstruktion komme ich nicht weiter.
if test "x${DIR}" = "x." || test -z "$DIR"; then DIR="$PWD"; fi
Ich verstehe die Bedingung nicht. BTW es gibt um avi-Videoschnipsel von einem Camcorder und nicht um mp3. Aufruf soll etwa so sein: video_rename.sh /verzeichnis/zu/videodateien Weder im Verzeichnis, noch im Dateinamen kommen Leerzeichen vor, aber wenn ich schon was neu schreibe, dann sollte es auch damit klar kommen. BTW gibt es eine Möglichkeit hunderte kleine avi-Dateien alfabetisch sortiert zusammenhängend abzuspielen? Wenn ich ein ganzes Band in einem Ordner habe, dann will ich nun die Themen trennen und in verschiedene Ordner schieben. Ich kann natürlich auf Verdacht eine Szene anklicken und mich näherungsweise herantasten.
find "${DIR}" -type d | while read d; do pushd "$d";
Wieder was dazu gelernt. (http://ss64.com/bash/pushd.html) Ich habe dafür dirname und basename verwendet.
i=0; for f in *.mp3; do test -d "$f" && continue; echo mv -i "$f" "${d##*\/}_$(printf "%05i.mp3" $i)";
das muss ich mir im Detail ansehen, wenn ich den Anfang verstanden habe.
i=$((i+1)); done; popd;
Auch noch nicht gekannt: http://ss64.com/bash/popd.html
done
Wenn du anders sortieren willst als es die Shell bei * macht
Das habe ich nicht verstanden. Was meinst du mit anders?
, dann mußt du z.B.
i=0; find .. | sort .. | while read -r file; do ..; done; i=$((i+1)
oder sowas verwenden.
Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Son, 14 Feb 2010, Al Bogner schrieb:
Am Sonntag, 14. Februar 2010 03:25:53 schrieb David Haller:
Am Sam, 13 Feb 2010, Al Bogner schrieb:
Am Samstag, 6. Februar 2010 20:24:20 schrieb David Haller:
Das zerbröselt's. for .. in `` oder $() ist _IMMER_ schlecht.
find "$DIR" -type f -iname '*.mp3' -exec /bin/bash -c 'for file; do lame ... "$file" "${file//.mp3}_128.mp3" done' find-bash '{}' '+'
Ich frage mich gerade wie ich folgendes ohne for hinkriege. Es geht zB darum, dass ein Skript alle gefundenen Dateien alfabetisch sortiert und diese dann durchnummeriert und als Dateinamen den Ordnernamen verwendet. Grundsätzlich wäre es mir mit for klar, aber mit Davids Konstruktion komme ich nicht weiter.
if test "x${DIR}" = "x." || test -z "$DIR"; then DIR="$PWD"; fi
Ich verstehe die Bedingung nicht. BTW es gibt um avi-Videoschnipsel von einem Camcorder und nicht um mp3.
Die Bedingungen testen, ob DIR '.' ist oder leer ist (denn dann verwendet find per default '.' als Startordner und dann ist der Verzeichnisname beim Umbenennen (s.u.) eben "." und damit nicht sinnvoll verwendbar. In dem Fall wird DIR eben auf $PWD gesetzt und man bekommt (s.u.) den Namen des Verzeichnisses. Mußt im Script halt .mp3 durch .avi ersetzen.
Aufruf soll etwa so sein:
video_rename.sh /verzeichnis/zu/videodateien
Weder im Verzeichnis, noch im Dateinamen kommen Leerzeichen vor, aber wenn ich schon was neu schreibe, dann sollte es auch damit klar kommen.
Sowieso ;)
BTW gibt es eine Möglichkeit hunderte kleine avi-Dateien alfabetisch sortiert zusammenhängend abzuspielen?
mplayer *.avi # du mußt alles laufen lassen for f in *.avi; do mplayer "$f"; done # du kannst einzelne clips # abbrechen
find "${DIR}" -type d | while read d; do pushd "$d";
Wieder was dazu gelernt. (http://ss64.com/bash/pushd.html) Ich habe dafür dirname und basename verwendet.
Ist ein kleiner Trick, damit man im jew. Verzeichnis arbeitet, dort dann die Dateiliste alphabetisch abarbeitet, und per popd wieder zurück (und das nächste Verz.).
i=0; for f in *.mp3; do test -d "$f" && continue; echo mv -i "$f" "${d##*\/}_$(printf "%05i.mp3" $i)";
das muss ich mir im Detail ansehen, wenn ich den Anfang verstanden habe.
Einfach gesagt: ${d##*\/} == $(basename "$d") == Verzeichnisname. printf formatiert den Zähler auf 5 Stellen. 00000 bis 99999 halt.
i=$((i+1)); done; popd;
Auch noch nicht gekannt: http://ss64.com/bash/popd.html
done
Wenn du anders sortieren willst als es die Shell bei * macht
Das habe ich nicht verstanden. Was meinst du mit anders?
Mach mal in nem Verz. mit nicht zu vielen Dateien echo * die bash sortiert das Ergebnis der Expansion alphabetisch bzw. gemäß LC_COLLATE. Und das reicht dir evtl. nicht. Achso, oder wolltest du _verzeichnisübergreifend_ alphabetisch sortieren und umbenennen? Oder nur, wie von mir angenommen, jew. pro Verzeichnis? Ersteres ginge auch, würde aber einige Trickserei mit Dateilisten erfordern. -dnh -- "DOS=HIGH ...I knew it was on something!" (UNIX user, while reading C:\CONFIG.SYS) -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Sonntag, 14. Februar 2010 18:17:01 schrieb David Haller: Hallo David,
Am Son, 14 Feb 2010, Al Bogner schrieb:
Am Sonntag, 14. Februar 2010 03:25:53 schrieb David Haller:
Am Sam, 13 Feb 2010, Al Bogner schrieb:
Am Samstag, 6. Februar 2010 20:24:20 schrieb David Haller:
Das zerbröselt's. for .. in `` oder $() ist _IMMER_ schlecht.
find "$DIR" -type f -iname '*.mp3' -exec /bin/bash -c 'for file; do lame ... "$file" "${file//.mp3}_128.mp3" done' find-bash '{}' '+'
Ich frage mich gerade wie ich folgendes ohne for hinkriege. Es geht zB darum, dass ein Skript alle gefundenen Dateien alfabetisch sortiert und diese dann durchnummeriert und als Dateinamen den Ordnernamen verwendet. Grundsätzlich wäre es mir mit for klar, aber mit Davids Konstruktion komme ich nicht weiter.
if test "x${DIR}" = "x." || test -z "$DIR"; then DIR="$PWD"; fi
Ich verstehe die Bedingung nicht. BTW es gibt um avi-Videoschnipsel von einem Camcorder und nicht um mp3.
Die Bedingungen testen, ob DIR '.' ist oder leer ist
Das habe ich mir schon so gedacht. Vielleicht fällt mir Basiswissen, das bis jetzt an mir vorbeigegangen ist. Normalerweise ist die Option $1. Ich verstehe aber nicht wie die übergeben wird.
(denn dann verwendet find per default '.' als Startordner und dann ist der Verzeichnisname beim Umbenennen (s.u.) eben "." und damit nicht sinnvoll verwendbar. In dem Fall wird DIR eben auf $PWD gesetzt und man bekommt (s.u.) den Namen des Verzeichnisses.
Du nimmst also an, dass das Verzeichnis abgearbeitet wird, in dem man sich befindet?
Mußt im Script halt .mp3 durch .avi ersetzen.
Schon klar. Ich habe nur den Anwendungsfall erwähnt, damit du dich besser hinein denken kannst, was ich will.
Aufruf soll etwa so sein:
video_rename.sh /verzeichnis/zu/videodateien
Siehe oben, wie ist das mit $1 ?
Weder im Verzeichnis, noch im Dateinamen kommen Leerzeichen vor, aber wenn ich schon was neu schreibe, dann sollte es auch damit klar kommen.
Sowieso ;)
BTW gibt es eine Möglichkeit hunderte kleine avi-Dateien alfabetisch sortiert zusammenhängend abzuspielen?
mplayer *.avi # du mußt alles laufen lassen
for f in *.avi; do mplayer "$f"; done # du kannst einzelne clips # abbrechen
Werde ich in der Praxis testen, sobald die verschiedenen Clips zusammengewürfelt wurden.
find "${DIR}" -type d | while read d; do pushd "$d";
Wieder was dazu gelernt. (http://ss64.com/bash/pushd.html) Ich habe dafür dirname und basename verwendet.
Ist ein kleiner Trick, damit man im jew. Verzeichnis arbeitet, dort dann die Dateiliste alphabetisch abarbeitet, und per popd wieder zurück (und das nächste Verz.).
i=0; for f in *.mp3; do test -d "$f" && continue; echo mv -i "$f" "${d##*\/}_$(printf "%05i.mp3" $i)";
das muss ich mir im Detail ansehen, wenn ich den Anfang verstanden habe.
Einfach gesagt: ${d##*\/} == $(basename "$d") == Verzeichnisname.
Muss ich noch besser verarbeiten
printf formatiert den Zähler auf 5 Stellen. 00000 bis 99999 halt.
ist klar
i=$((i+1)); done; popd;
Auch noch nicht gekannt: http://ss64.com/bash/popd.html
done
Wenn du anders sortieren willst als es die Shell bei * macht
Das habe ich nicht verstanden. Was meinst du mit anders?
Mach mal in nem Verz. mit nicht zu vielen Dateien
echo *
die bash sortiert das Ergebnis der Expansion alphabetisch bzw. gemäß LC_COLLATE. Und das reicht dir evtl. nicht.
Vermutlich schon. Ein Band hat Dateiname + Nummer, manchmal ist eine Bandnummer vor dem Text. 024_coteazur_3_0001.avi 024_coteazur_3_0002.avi ... 024_coteazur_3_0259.avi 024_coteazur_3_0260.avi Irgendwo wird es noch avi-Dateinamen mit Datum und Uhrzeit geben, so was ist mir noch nicht untergekommen, sollte aber egal sein.
Achso, oder wolltest du _verzeichnisübergreifend_ alphabetisch sortieren
Das hätte ich mir schon gewünscht. Als Option wird ein Verzeichnis angegeben, überprüft, ob dieses existiert und dann mit find alle avi-Dateien gesucht, die alfabetisch sortiert und dann mit dem Ordnernamen durchnummeriert. 4 stellen sollten reichen, also max. 000x.
und umbenennen? Oder nur, wie von mir angenommen, jew. pro Verzeichnis? Ersteres ginge auch, würde aber einige Trickserei mit Dateilisten erfordern.
Mit for und ohne Leerzeichne im Dateinamen habe ich da wenig getrickst ;-) Einfach find ... | sort. Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Son, 14 Feb 2010, Al Bogner schrieb:
Am Sonntag, 14. Februar 2010 18:17:01 schrieb David Haller:
Am Son, 14 Feb 2010, Al Bogner schrieb:
Am Sonntag, 14. Februar 2010 03:25:53 schrieb David Haller: [..]
if test "x${DIR}" = "x." || test -z "$DIR"; then DIR="$PWD"; fi
Ich verstehe die Bedingung nicht. BTW es gibt um avi-Videoschnipsel von einem Camcorder und nicht um mp3.
Die Bedingungen testen, ob DIR '.' ist oder leer ist
Das habe ich mir schon so gedacht. Vielleicht fällt mir Basiswissen, das bis jetzt an mir vorbeigegangen ist.
Normalerweise ist die Option $1. Ich verstehe aber nicht wie die übergeben wird.
Dann denk dir ein 'DIR="$1"' als erste Zeile nach #!/bin/bash ;) Ich nahm bisher an, daß das nicht unbedingt als script gedacht ist.
(denn dann verwendet find per default '.' als Startordner und dann ist der Verzeichnisname beim Umbenennen (s.u.) eben "." und damit nicht sinnvoll verwendbar. In dem Fall wird DIR eben auf $PWD gesetzt und man bekommt (s.u.) den Namen des Verzeichnisses.
Du nimmst also an, dass das Verzeichnis abgearbeitet wird, in dem man sich befindet?
Nein. Das, was per DIR (s.o.) übergeben wird. Dort wird dann jedes Unterverzeichnis _einzeln_ verwurstet (d.h. die darin befindlichen *.avi umbenannt). Das ist die pushd+popd Geschichte. [..]
Einfach gesagt: ${d##*\/} == $(basename "$d") == Verzeichnisname.
Muss ich noch besser verarbeiten
man bash -> nach :- suchen, da landest du IIRC recht genau in dem Abschnitt wo das erklärt wird.
die bash sortiert das Ergebnis der Expansion alphabetisch bzw. gemäß LC_COLLATE. Und das reicht dir evtl. nicht.
Vermutlich schon.
Ein Band hat Dateiname + Nummer, manchmal ist eine Bandnummer vor dem Text.
024_coteazur_3_0001.avi 024_coteazur_3_0002.avi
Dann dürfte Sortierung nach LC_COLLATE=POSIX oder =de_DE reichen, d.h. man könnte wohl schlicht die Shell den '*' expandieren lassen und sich ein explizites 'sort' sparen. Aber s.u.
Achso, oder wolltest du _verzeichnisübergreifend_ alphabetisch sortieren
Das hätte ich mir schon gewünscht.
Als Option wird ein Verzeichnis angegeben, überprüft, ob dieses existiert und dann mit find alle avi-Dateien gesucht, die alfabetisch sortiert und dann mit dem Ordnernamen durchnummeriert. 4 stellen sollten reichen, also max. 000x.
_WO_ willst du sortieren? Innerhalb a) jedes einzelnen Unterverzeichnisses oder willst du _alle_ Dateien ab dem Startverzeichnis b) mit oder c) ohne die jew. Unterver- zeichnisse sortieren?
und umbenennen? Oder nur, wie von mir angenommen, jew. pro Verzeichnis? Ersteres ginge auch, würde aber einige Trickserei mit Dateilisten erfordern.
Mit for und ohne Leerzeichne im Dateinamen habe ich da wenig getrickst ;-)
Einfach find ... | sort.
Das wäre Variante b). Sortiert wird "nach Text" die Dateiliste, wie sie ein find . -type f | sort ausspuckt, und die Dateien dieser Liste dann eben umbenamst? Also z.B. alle Dateien aus ./bla/ landen (umbenamst) vor allen Datein aus ./foo/? Also z.B.: ./bla/bla_0001.avi \ ... > = alles aus bla ./bla/bla_0123.avi / ./foo/foo_0124.avi \ ... > = alles aus foo ./foo/foo_0154.avi / Das wäre schon (bis auf das bestimmen des Verzichnisnamens) wieder trivial. find | sort und ne Zählervariable. Mail mir doch evtl mal ein _konkretes_ (gekürztes) Beispiel per PM. -dnh -- "Wenn das Wörtchen 'wenn' nicht wär' , wär' die Platte jetzt nicht leer." -- ratti in suse-linux -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Sonntag, 14. Februar 2010 20:11:21 schrieb David Haller: Hallo David,
Normalerweise ist die Option $1. Ich verstehe aber nicht wie die übergeben wird.
Dann denk dir ein 'DIR="$1"' als erste Zeile nach #!/bin/bash ;)
Hatte ich, aber dann nur die Hälfte kapiert. Bei dir rechne ich immer, dass du eine Konstruktion hast, die für mich Neuland ist, aber eigentlich war es trivial.
Ich nahm bisher an, daß das nicht unbedingt als script gedacht ist.
Ich denke das wird am besten sein. So ganz genau weiß ich noch nicht, was ich will. gegeben sind zigtausend oder vielleicht hundertausende avi-Schnipsel, die in Ordner zugeordnet werden müssen. Eventuell kann ich die Sortierung nur erreichen, indem ich 2 mal die Dateien im Ordner durch das Skript umbenenne und erst dann verschiebe. Die Praxis wird es zeigen. Es werden aber noch einige Tage vergehen, bis ich damit anfangen kann.
(denn dann verwendet find per default '.' als Startordner und dann ist der Verzeichnisname beim Umbenennen (s.u.) eben "." und damit nicht sinnvoll verwendbar. In dem Fall wird DIR eben auf $PWD gesetzt und man bekommt (s.u.) den Namen des Verzeichnisses.
Du nimmst also an, dass das Verzeichnis abgearbeitet wird, in dem man sich befindet?
Nein. Das, was per DIR (s.o.) übergeben wird. Dort wird dann jedes Unterverzeichnis _einzeln_ verwurstet (d.h. die darin befindlichen *.avi umbenannt). Das ist die pushd+popd Geschichte.
[..]
Einfach gesagt: ${d##*\/} == $(basename "$d") == Verzeichnisname.
Muss ich noch besser verarbeiten
man bash -> nach :- suchen, da landest du IIRC recht genau in dem Abschnitt wo das erklärt wird.
die bash sortiert das Ergebnis der Expansion alphabetisch bzw. gemäß LC_COLLATE. Und das reicht dir evtl. nicht.
Vermutlich schon.
Ein Band hat Dateiname + Nummer, manchmal ist eine Bandnummer vor dem Text.
024_coteazur_3_0001.avi 024_coteazur_3_0002.avi
Dann dürfte Sortierung nach LC_COLLATE=POSIX oder =de_DE reichen, d.h. man könnte wohl schlicht die Shell den '*' expandieren lassen und sich ein explizites 'sort' sparen. Aber s.u.
Achso, oder wolltest du _verzeichnisübergreifend_ alphabetisch sortieren
Das hätte ich mir schon gewünscht.
Als Option wird ein Verzeichnis angegeben, überprüft, ob dieses existiert und dann mit find alle avi-Dateien gesucht, die alfabetisch sortiert und dann mit dem Ordnernamen durchnummeriert. 4 stellen sollten reichen, also max. 000x.
_WO_ willst du sortieren?
Innerhalb a) jedes einzelnen Unterverzeichnisses oder willst du _alle_ Dateien ab dem Startverzeichnis b) mit oder c) ohne die jew. Unterver- zeichnisse sortieren?
Genau genommen werde ich das erst in der Praxis feststellen, was ich brauche, theoretisch denke ich mir, dass ich in der Regel keine Unterverzeichnisse brauche, aber es könnte notwendig oder zumindest einfacher werden, zB wenn aus mehreren Ordnern zusammengemischt wird. Ich nehme folgendes an. Im Ordner A und B und C befinden sich Dateien, die ich in einen Ordner D verschiebe, der oberhalb von A, B und C ist, d.h. unterhalb von D befinden sich keine Dateien und nur Ordner, worin sich dann aber Dateien befinden. Nun sollen alle Dateien umbenannt und verschoben werden. Die Dateien erhalten also den Namen von Ordner D und werden unterhalb von D geschoben. In A, B und C befinden sich dann also keine avi-Dateien mehr. Eventuelle andere Dateien sollen in A, B und C erhalten bleiben. Letztlich wird sich alles danach richten, wie ich zusammengehörende Dateien am besten organsiere bzw. manuell zuordne, bevor das Skript darüber läuft.
und umbenennen? Oder nur, wie von mir angenommen, jew. pro Verzeichnis? Ersteres ginge auch, würde aber einige Trickserei mit Dateilisten erfordern.
Mit for und ohne Leerzeichne im Dateinamen habe ich da wenig getrickst ;-)
Einfach find ... | sort.
Das wäre Variante b). Sortiert wird "nach Text" die Dateiliste, wie sie ein find . -type f | sort ausspuckt, und die Dateien dieser Liste dann eben umbenamst? Also z.B. alle Dateien aus ./bla/ landen (umbenamst) vor allen Datein aus ./foo/? Also z.B.:
./bla/bla_0001.avi \ ... > = alles aus bla ./bla/bla_0123.avi / ./foo/foo_0124.avi \ ... > = alles aus foo ./foo/foo_0154.avi /
Das wäre schon (bis auf das bestimmen des Verzichnisnamens) wieder trivial. find | sort und ne Zählervariable.
So habe ich es mir vorgestellt, aber du hast mir andere Möglichkeiten bewusst gemacht.
Mail mir doch evtl mal ein _konkretes_ (gekürztes) Beispiel per PM.
Es ist noch vieles theoretisch. Ich kann dir kein ls oder so schicken, das was bringt. Ich hoffe mein obiges Beispiel ist klar. Primär wäre das wichtig Ordnername: frankreich: 024_coteazur_3_0001.avi 024_coteazur_3_0002.avi 024_coteazur_3_0259.avi 024_coteazur_3_0260.avi Dateien werden umbenannt in: 024_coteazur_3_0001.avi -> frankreich_0001.avi 024_coteazur_3_0002.avi -> frankreich_0002.avi 024_coteazur_3_0259.avi -> frankreich_0003.avi 024_coteazur_3_0260.avi -> frankreich_0004.avi Gibt es Unterverzeichnisse und nehmen wir für alle Fälle die unwahrscheinliche Situation an, dass sich auch direkt darunter Dateien befinden, dann soll sich folgendes ergeben: Ordnername: frankreich: 024_coteazur_3_0001.avi 024_coteazur_3_0002.avi 024_coteazur_3_0259.avi 024_coteazur_3_0260.avi darunter ein Verzeichnis museum irgendwas_0001.avi irgendwas_0002.avi darunter ein Verzeichnis konzert auchwas_0001.avi auchwas_0002.avi Für die Sortierung ist "museum" und "konzert" unerheblich, sortiert wird nur nach dem Dateinamen. Also 024_coteazur_3_0001.avi 024_coteazur_3_0002.avi 024_coteazur_3_0259.avi 024_coteazur_3_0260.avi auchwas_0001.avi auchwas_0002.avi irgendwas_0001.avi irgendwas_0002.avi und das wird dann umbenannt in 024_coteazur_3_0001.avi -> frankreich_0001.avi 024_coteazur_3_0002.avi -> frankreich_0002.avi 024_coteazur_3_0259.avi -> frankreich_0003.avi 024_coteazur_3_0260.avi -> frankreich_0004.avi auchwas_0001.avi -> frankreich_0005.avi auchwas_0002.avi -> frankreich_0006.avi irgendwas_0001.avi -> frankreich_0007.avi irgendwas_0002.avi -> frankreich_0008.avi Wenn das zu kompliziert ist, dann reicht auch Variante 1. Dann muss ich das eben manuell machen und 2x das Skript laufen lassen. Wie schon geschrieben, die Details werde ich erst wissen, wenn ich zusammengehörende Dateien verschiebe und dabei auf Ideen komme, wie ich am besten den Überblick behalte. Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Sonntag, 14. Februar 2010 03:25:53 schrieb David Haller: Hallo David,
Wenn du anders sortieren willst als es die Shell bei * macht, dann mußt du z.B.
i=0; find .. | sort .. | while read -r file; do ..; done; i=$((i+1)
oder sowas verwenden.
Ich habe mich für eine simple Variante entschieden und ergänze bei Bedarf. Allerdings verstehe ich überhaupt nicht, warum ich 1 Band komplett verlor als ich 2 Bänder mischte. Zum Glück habe ich nun doch eine Sicherung der eingelesen Bänder gemacht. Siehst du hier was verdächtiges? Das hat bereits zig Male problemlos funktioniert. #!/bin/bash cd "$1" TOPIC=`basename "$1"` MYDIR=`pwd` # wirft auch Leerzeichen und Sonderzeichen raus /usr/local/bin/dateiname_gross_klein_wandlung "$1" i=1 find "$1" -type f -regex ".*\.avi$" | sort | while read -r FILE; do NEWFILE="$MYDIR""/""${TOPIC##*\/}_$(printf "%04i.avi" $i)" mv "$FILE" "$NEWFILE" i=$((i+1)) done Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Don, 18 Feb 2010, Al Bogner schrieb: [..]
Siehst du hier was verdächtiges? Das hat bereits zig Male problemlos funktioniert.
#!/bin/bash [..] find "$1" -type f -regex ".*\.avi$" | sort | while read -r FILE; ^^^^^^^^^^^^^^^^^ == -name '*.avi' (und das wäre schneller, da ein einfacher glob/Stringvergleich reicht und nicht ne RE geparst und gematcht werden muß.
do
NEWFILE="$MYDIR""/""${TOPIC##*\/}_$(printf "%04i.avi" $i)"
NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)"
mv "$FILE" "$NEWFILE"
Du fängt Kollisionen nicht ab! Am einfachsten: mv -i "$FILE" "$NEWFILE"
i=$((i+1)) done
HTH, -dnh -- Alkohol tötet langsam. Aber ich habe Zeit. -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Donnerstag, 18. Februar 2010 23:32:02 schrieb David Haller: Hallo David,
Am Don, 18 Feb 2010, Al Bogner schrieb: [..]
Siehst du hier was verdächtiges? Das hat bereits zig Male problemlos funktioniert.
#!/bin/bash
[..]
find "$1" -type f -regex ".*\.avi$" | sort | while read -r FILE;
^^^^^^^^^^^^^^^^^ == -name '*.avi' (und das wäre schneller, da ein einfacher glob/Stringvergleich reicht und nicht ne RE geparst und gematcht werden muß.
Stimmt, ich vergesse das immer wieder, weil ich mit regex auch schnell mal komplizierteres testweise machen kann. Bei etwa max. 500 Dateien in einem Verzeichnis bis jetzt, fiel das aber nicht auf.
do
NEWFILE="$MYDIR""/""${TOPIC##*\/}_$(printf "%04i.avi" $i)"
NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)"
mv "$FILE" "$NEWFILE"
Du fängt Kollisionen nicht ab! Am einfachsten:
mv -i "$FILE" "$NEWFILE"
Hmm, will ich das in meinem Fall? Eine Kolliision ist nur dann denkbar, wenn ich das Script ein 2. x aufrufe und die Datei durch sich selbst ersetzt werden soll. In diesem Fall soll gar nichts passieren. Das ist mir auch schon passiert und dann gibt es Fehlermeldungen, die ich ignorieren kann. Da die Dateien aus einem Capture stammen, haben sie immer das selbe Schema und auch nicht zufällig denselben Dateinamen in den umbenannt werden soll. Aber du hast recht, das könnte den Fall erklären, wo ich Dateien verloren habe. Wenn ich 1x das Skript bereits habe laufen lassen und nachträglich Dateien dazu oder weg gebe und das Script wieder laufen lasse, kommt es zu einer Kollision. Nur will ich dann nicht 500x gefragt werden. Bei der 1. Datei sollte dann einfach auf die Kollision hingewiesen werden und abgebrochen werden. Wie mache ich das effizient? Mit "if -f" ? Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Fre, 19 Feb 2010, Al Bogner schrieb:
Am Donnerstag, 18. Februar 2010 23:32:02 schrieb David Haller: [..]
Du fängt Kollisionen nicht ab! Am einfachsten:
mv -i "$FILE" "$NEWFILE"
Hmm, will ich das in meinem Fall?
Normal will man das.
Nur will ich dann nicht 500x gefragt werden. Bei der 1. Datei sollte dann einfach auf die Kollision hingewiesen werden und abgebrochen werden.
Strg+c Müßte auch ohne ein eigenes 'trap ... INT' gehen.
Wie mache ich das effizient? Mit "if -f" ?
Nein. Die Zieldatei könnte auch ein symlink sein. Oder ne named-pipe. Oder ein Socket. Der symlink-Fall dürfte unmittelbar einleuchten, named-pipe z.B. dann, wenn ein Programm unbedingt ne Datei haben will (und nicht stdout/stdin) ... Socket eher nicht ;) Egal. Jedenfalls will man nicht auf "ist es ne normale Datei?" prüfen, sondern auf "existiert die Zieldatei?", ergo: if test -e "$NEWFILE"; then # ### ggfs. noch ne Ausgabe, z.B.: # echo "$NEWFILE already exists" >&2 exit 17; ## abbrechen # continue; ## überspringen # davorschalten fi Üblicherweise schreib ich das direkt nachdem alle für den Test "da" ist, also hier, sobald "NEWFILE" zugewiesen wurde und dann ohne if: {LOOP} [..] NEWFILE=.... test -e "$NEWFILE" && { echo "File exists: '$NEWFILE'" >&2; exit 17; } # if test -e "$NEWFILE"; then # echo "File exists: '$NEWFILE'. Skipping '$FILE'" >&2; # continue; # fi mv -i "$FILE" "$NEWFILE" ### das -i dürfte nie anspringen, falls ### doch (aus welchem Grund auch immer das ### 'test -e' false lieferte), dann dürfte ### man froh sein, daß es angegeben ist. ;) [..] {ENDLOOP} Das 'exit 17' eher beispielhaft, aber 17 ist die Fehlernummer von "EEXIST"/"File exists"/"Die Datei existiert bereits" (siehe auch less /usr/include/asm/errno.h bzw. passend zum aktuellen Kernel: less /lib/modules/$(uname -r)/build/include/asm/errno.h wenn die Kernelquellen installiert und vorbereitet sind. HTH, -dnh P.S: das && { foo; bar; } geht auch mehrzeilig. Aber dann ist doch meist if/fi lesbarer. -- Masturbation ist Sex an und für sich. -- geklaut von Hauke Heidtmann -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Freitag, 19. Februar 2010 04:20:19 schrieb David Haller: Hallo David,
Am Fre, 19 Feb 2010, Al Bogner schrieb:
Am Donnerstag, 18. Februar 2010 23:32:02 schrieb David Haller:
[..]
Du fängt Kollisionen nicht ab! Am einfachsten:
mv -i "$FILE" "$NEWFILE"
Hmm, will ich das in meinem Fall?
Normal will man das.
Das kann ich mir schon vorstellen, gerade nachdem ich auf das Problem gestoßen bin, wenn nachträglich Dateien dazu oder wegkommen. So weit war ich aber noch nicht. Ich habe bis jetzt nur Dateien verschoben ohne welche aus der Mitte herauszulöschen und ein 2. Mal das Script laufen zu lassen. Gott sei Dank ;-) BTW das Sortieren der Clips geht ganz gut mit der Konqueror-Videovorschau. Allerdings ist mir KDE via NFS mehrmals grausam eingegangen. Wenn ich direkt am Server verschiebe, ist es meistens problemlos, es gab aber auch schon Probleme. Gibt es andere Windowmanager, die Vorschaubilder von avi-Videoclips anzeigen können? KDE treibt mich mal wieder sehr an die Schmerzgrenze ;-) Ich glaube aber, dass ich das Konfliktproblem besser organisatorisch löse und so den Konflikt ausschließe. Wenn -i aktiv wird, dann habe ich nämlich schon einen organisatorischen Fehler beim Zusammenwürfeln der Ckips gemacht. Ich denke, ich benenne 2x um, sodass es keine Kollision geben kann und lasse - i für alle Fälle. ____________________________________________ #!/bin/bash cd "$1" TOPIC=`basename "$1"` MYDIR=`pwd` /usr/local/bin/dateiname_gross_klein_wandlung "$1" i=1 find "$1" -type f -name '*.avi' | sort | while read -r FILE; do NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)"".tmpavi" mv -i "$FILE" "$NEWFILE" i=$((i+1)) done find "$1" -type f -name '*.tmpavi' | sort | while read -r FILE; do NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)" mv -i "$FILE" "$NEWFILE" i=$((i+1)) done ____________________________________________
Nur will ich dann nicht 500x gefragt werden. Bei der 1. Datei sollte dann einfach auf die Kollision hingewiesen werden und abgebrochen werden.
Strg+c
Müßte auch ohne ein eigenes 'trap ... INT' gehen.
Wie mache ich das effizient? Mit "if -f" ?
Nein. Die Zieldatei könnte auch ein symlink sein. Oder ne named-pipe. Oder ein Socket. Der symlink-Fall dürfte unmittelbar einleuchten, named-pipe z.B. dann, wenn ein Programm unbedingt ne Datei haben will (und nicht stdout/stdin) ... Socket eher nicht ;) Egal. Jedenfalls will man nicht auf "ist es ne normale Datei?" prüfen, sondern auf "existiert die Zieldatei?", ergo:
if test -e "$NEWFILE"; then # ### ggfs. noch ne Ausgabe, z.B.: # echo "$NEWFILE already exists" >&2 exit 17; ## abbrechen # continue; ## überspringen # davorschalten fi
Üblicherweise schreib ich das direkt nachdem alle für den Test "da" ist, also hier, sobald "NEWFILE" zugewiesen wurde und dann ohne if:
Gute Idee, danke.
{LOOP} [..] NEWFILE=.... test -e "$NEWFILE" && { echo "File exists: '$NEWFILE'" >&2; exit 17; } # if test -e "$NEWFILE"; then # echo "File exists: '$NEWFILE'. Skipping '$FILE'" >&2; # continue; # fi mv -i "$FILE" "$NEWFILE" ### das -i dürfte nie anspringen, falls ### doch (aus welchem Grund auch immer das ### 'test -e' false lieferte), dann dürfte ### man froh sein, daß es angegeben ist. ;)
Das habe ich mir auch gedacht.
[..] {ENDLOOP}
Das 'exit 17' eher beispielhaft, aber 17 ist die Fehlernummer von "EEXIST"/"File exists"/"Die Datei existiert bereits" (siehe auch less /usr/include/asm/errno.h bzw. passend zum aktuellen Kernel: less /lib/modules/$(uname -r)/build/include/asm/errno.h wenn die Kernelquellen installiert und vorbereitet sind.
HTH, -dnh
P.S: das && { foo; bar; } geht auch mehrzeilig. Aber dann ist doch meist if/fi lesbarer.
Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Donnerstag, 18. Februar 2010 23:32:02 schrieb David Haller: Hallo David,
NEWFILE="$MYDIR""/""${TOPIC##*\/}_$(printf "%04i.avi" $i)"
NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)"
Wo liegt der Unterschied beim Quoting? NEWFILE="$MYDIR""/" NEWFILE="${MYDIR}/ Al -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Fre, 19 Feb 2010, Al Bogner schrieb:
Am Donnerstag, 18. Februar 2010 23:32:02 schrieb David Haller:
NEWFILE="$MYDIR""/""${TOPIC##*\/}_$(printf "%04i.avi" $i)"
NEWFILE="${MYDIR}/${TOPIC##*\/}_$(printf '%04i.avi' $i)"
Wo liegt der Unterschied beim Quoting?
NEWFILE="$MYDIR""/" NEWFILE="${MYDIR}/
Letzteres ist besser lesbar. Einen Beleg lieferst du praktischerweise gleich mit: du hast das wieder -Aöffnende " am Ende vergessen ;)-b -dnh -- Angela Merkel ist eine Frau! -- Auf welchem Parteitag wurde das beschlossen? -- Marco Haschka, Sebastian Jarosch -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
participants (2)
-
Al Bogner
-
David Haller