2016-06-19 17 views
2

Ich habe ein Verzeichnis mit mehreren Unterverzeichnissen, die .flac Dateien enthalten. Ich möchte sie zu .mp3 Batch konvertieren. Die Pfadnamen enthalten Leerzeichen. Jetzt möchte ich so etwas wie diesesBatch-Prozess-Dateien mit finden in mehreren Verzeichnissen

find . -type f -regex .*.flac -exec ffmpeg -i {} -c:a mp3 -b:a 320k \; 

tun, aber die Frage ist, wie kann ich {} und Ersatz flac für mp3 eine Ausgabedateinamen geben ffmpeg? In bash könnte man die Variablensubstitution ${file%.flac}.mp3 verwenden, aber ich kann das hier nicht anwenden. sed -basierte Ansätze scheinen nicht mit find entweder zu arbeiten. Gibt es dafür eine einfache Lösung?

+1

BTW. zitieren '* .flac'. – Cyrus

Antwort

3

Wenn Sie bash verwenden, würde ich globstar verwenden, die auf die Liste aller .flac Dateien erweitern:

shopt -s globstar nullglob 
for file in **/*.flac; do 
    [[ -f $file ]] || continue 
    out_file=${file%.flac}.mp3 
    ffmpeg # your options here, using "$out_file" 
done 

Die Prüfung [[ -f $file ]] alle Verzeichnisse überspringt, die in .flac beenden. Sie könnten dies wahrscheinlich überspringen, wenn Sie keine von denen haben.

Ich habe auch die Shell-Option nullglob aktiviert, so dass ein Muster, das nicht mit Dateien übereinstimmt, zu nichts erweitert (so dass die Schleife nicht ausgeführt wird).

+0

Dann verdienst du mein Plus-One ':)'. –

2

Wenn Sie wirklich find verwenden möchten (z. B. Sie stecken in der Vergangenheit mit einer antiken Version von Bash und globstar ist nicht verfügbar - also Tom Fenech Lösung ist keine Option), müssen Sie eine spawnen Shell, um die Ersetzung durchzuführen. Der normale Weg wäre:

find . -name '*.flac' -type f -exec sh -c 'ffmpeg -i "$1" -c:a mp3 -b:a 320k "${1%.flac}.mp3"' dummy {} \; 

sh -c sein erstes Argument laufen, und die Teilfolge Argumente werden an die Positionsparameter eingestellt von 0 starten. Deshalb habe ich einen Dummy-Parameter (und ich nannte es dummy, aber alles andere könnte tun).

Beachten Sie, dass in find-name das Argument *.flac zitiert werden muss. Aus irgendeinem Grund haben Sie Ihren Beitrag bearbeitet und das Prädikat -name durch ein Prädikat -regex ersetzt: Es ist wirklich nutzlos, und Sie müssen das Argument trotzdem zitieren.

+0

Ist es nicht möglich, 'sh -c 'ffmpeg -i" $ 0 "-c zu schreiben: a mp3 -b: a 320k" $ {1% .flac} .mp3 "' {} \;' –

+1

@mona_sax: nein , das ist nicht ganz gültig, da in diesem Fall der Positionsparameter '$ 1' nicht gesetzt ist! vielleicht meinst du: 'sh -c 'ffmpeg -i" $ 0 "-c: ein mp3 -b: ein 320k" $ {0% .flac} .mp3 "' {} \;', und das ist vollkommen richtig. –

+1

Nun ja !! Ich meine, was du gerade gesagt hast. :). Ich wollte vermeiden, eine Dummy-Variable zu verwenden. Dies ist in der Tat eine elegante Einlage :) +1 –