ubuntuusers.de

wma-Dateien mit find finden und mit avconv in mp3 konvertieren?

Status: Ungelöst | Ubuntu-Version: Ubuntu 14.10 (Utopic Unicorn)
Antworten |

Toledo_Thomas

Avatar von Toledo_Thomas

Anmeldungsdatum:
18. November 2007

Beiträge: 141

Moin!

ich würde gerne die wma-Dateien in meiner Musiksammlung mit find und avconv zu mp3 konvertieren. Mit der find (Abschnitt „Aktionen“)-Aktion -execdir sollte das doch möglich sein oder? Also, dass ich für jede gefundene Datei avconv im jeweiligen Verzeichnis aufrufe.

Mein bisheriger "Code-Schnipsel" sieht so aus:

1
find /pfad/zur/Musik/ -iname *.wav -execdir sh -c 'avconv -i ${0} -acodec libmp3lame -ab 192k -ar 44100 ${0}.mp3' {} \;

Vom Prinzip her müsste das doch so möglich sein oder? Was die Syntax angeht sind da aber sicherlich mehrere Fehler. Wenn die Endung wma leicht zu entfernen ist, wär das schön, ist aber nicht so wichtig. Ich kann sonst auch mit meinem ID3Tag-Programm aus dem Tag einen Dateinamen erstellen. Wir wollen es ja erstmal einfach halten..

Was mir aufgefallen ist, und wohl als Sicherheitsfeature gilt, ist dass find an die gefundenen Dateien ein ./ voranstellt. Ich hab das eher als hinderlich empfunden 😉 auf jeden Fall sind mir bisher keine Befehle mit find in Verbindung mit execdir geglückt. Dazu kommt noch, dass ich noch nicht herausgefunden hab, wie avconv (Abschnitt „Beispiele“) am besten verwendet wird.

Also, für Vorschläge bin ich dankbar.

Thomas

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

Toledo Thomas schrieb:

Was mir aufgefallen ist, und wohl als Sicherheitsfeature gilt, ist dass find an die gefundenen Dateien ein ./ voranstellt. Ich hab das eher als hinderlich empfunden 😉 auf jeden Fall sind mir bisher keine Befehle mit find in Verbindung mit execdir geglückt.

Vielleicht zeigst Du mal, was Du versucht hast. Dann können wir Dir vielleicht sagen, wo es hakt.

Ich würde "-exec" verwenden und nicht "-execdir" - es gibt keinen Grund, das Verzeichnis zu wechseln.

Dazu kommt noch, dass ich noch nicht herausgefunden hab, wie avconv (Abschnitt „Beispiele“) am besten verwendet wird.

Grobe Idee:

1
2
3
4
5
6
find -type f -name '*.wma' -exec sh -c '
for f; do
  target="${f%.wma}.mp3"
  avconv -i "$f" -acodec mp3 -b 192k -ar 44100 "$target" # && rm "$f"
done
' -- +

Den rm kann man einkommentieren um das Original zu löschen, wenn die Umwandlung geklappt hat.

Ciao

robert

Toledo_Thomas

(Themenstarter)
Avatar von Toledo_Thomas

Anmeldungsdatum:
18. November 2007

Beiträge: 141

Manchmal vergeht die Zeit so schnell.. Habs nun nicht mehr geschafft, das zu testen, aber danke für den Ansatz. Morgen Abend klappts bestimmt 😉 Eine for-Schleife in Verbindung mit find hab ich auch schon gesehen. Ich muss aber sagen, ich versteh das Prinzip nicht so ganz.

1) Eigentlich ist es doch so, dass für jede gefundene Datei sofort der Befehl der hinter -exec steht ausgeführt wird. Bei Verwendung einer for-Schleife würde ich annehmen, dass eine Liste erstellt wurde, die anschließend von der Schleife abgearbeitet wird.
2) Mir ist auch sonst noch nicht klar, warum ich sh -c schreiben muss, obwohl ich find ja in der Shell aufrufe.
3) Und warum der eigentliche Befehl in Hochkommatas steht
4) und in deinem Beispiel das Ganze auf – + endet statt auf {} \; (wie im Wiki)
Wenn du Zeit und Lust hast, freu ich mich, wenn du mir das erläutern würdest.

Achso zu der Begründung für das vorangestellte ./ hatte ich diese Seite gefunden: https://www.gnu.org/software/findutils/manual/html_node/find_html/Problems-with-_002dexec-and-filenames.html

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

1
find /pfad/zur/Musik/ -iname *.wav -execdir sh -c 'avconv -i ${0} -acodec libmp3lame -ab 192k -ar 44100 ${0}.mp3' {} \;

Ich würde es ohne sh -c probieren.

1
find /pfad/zur/Musik/ -iname *.wav -execdir avconv -i {} -acodec libmp3lame -ab 192k -ar 44100 {}.mp3 \;

Zum Testen rufe ich es mit echo auf, da ich kein avconv habe und nichts konvertieren möchte:

1
find . -iname "*.wav" -execdir echo avconv -i {} -acodec libmp3lame -ab 192k -ar 44100 {}.mp3 \;

Das klappt mit unauffälligem Befund.

Geht es nur darum den Namen nicht auf wav.mp3 enden zu lassen? Das würde ich am Ende mit einem rename reparieren:

1
rename 's/.wav.mp3/.mp3' *.wav.mp3

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

Toledo Thomas schrieb:

1) Eigentlich ist es doch so, dass für jede gefundene Datei sofort der Befehl der hinter -exec steht ausgeführt wird. Bei Verwendung einer for-Schleife würde ich annehmen, dass eine Liste erstellt wurde, die anschließend von der Schleife abgearbeitet wird.

Genau. Siehe die Manpage von find. Achte insbesondere auf "{} +" anstatt des oft gesehenen "{} \;".

2) Mir ist auch sonst noch nicht klar, warum ich sh -c schreiben muss, obwohl ich find ja in der Shell aufrufe.

Weil Du von find aus eine Shell pro N Dateien startest und in dieser Shell dann das Skript ausgeführt wird, das nach -c folgt.

3) Und warum der eigentliche Befehl in Hochkommatas steht

Das nennt man "Quoting". Das muss hier gemacht werden, damit es für die aktuelle Shell ein Parameter ist.

4) und in deinem Beispiel das Ganze auf – + endet statt auf {} \; (wie im Wiki)

s.o. Zusätzlich sei erwähnt, dass man noch ein Argument nach dem Kommando braucht, weil das auf $0 gepackt wird, aber $@ nur Parameter ab $1 enthält:

$ touch $(seq 1 10)
$ ls
1  10  2  3  4  5  6  7  8  9
$ find -type f -exec sh -c 'echo "$@"' {} +
./10 ./2 ./3 ./4 ./5 ./6 ./7 ./8 ./9
$ find -type f -exec sh -c 'echo "$@"' -- {} +
./1 ./10 ./2 ./3 ./4 ./5 ./6 ./7 ./8 ./9 

Achso zu der Begründung für das vorangestellte ./ hatte ich diese Seite gefunden: https://www.gnu.org/software/findutils/manual/html_node/find_html/Problems-with-_002dexec-and-filenames.html

Der von mir gezeigte Code hat das genannte Problem nicht, da er die Lösung am Ende der Seite benutzt. Du siehst nur kein "$@", weil das implizit ist, wenn for .. kein in Werte folgt.

Im aktuellen Fall ist uu's Lösung vielleicht einfacher. Du hast halt nur am Ende Dateien, die auf ".wma.mp3" enden und die ".wma" werden nicht weggeräumt.

Ich hätte noch eine kleine Variante für den Fall, dass manche Dateien auf ".WMA" enden:

1
2
3
4
5
6
find -type f -iname '*.wma' -exec sh -c '
for f; do
  target="${f%.*}.mp3"
  avconv -i "$f" -acodec mp3 -b 192k -ar 44100 "$target" # && rm "$f"
done
' -- +

Änderungen:

  1. -iname statt -name

  2. bei der Ersetzung wird ".*" anstatt ".wma" verwendet.

Noch eine Bitte: nutz doch die Möglichkeiten des Forums Aufzählungen zu formatieren. Das Ergebnis ist für alle lesbarer und Du musst auch nicht am Ende jeder Zeile einen manuellen Zeilenumbruch setzen.

Ciao

robert

Antworten |