Reputation: 7827
On this .ogg
files
$ tree
.
├── Disc 1 - 01 - Procrastination.ogg
├── Disc 1 - 02 - À carreaux !.ogg
├── Disc 1 - 03 - Météo marine.ogg
└── mp3
I try with a while
loop to ffmpeg convert them to mp3 keeping spaces in filenames::
$ ls *.ogg | while read line; do ffmpeg -i "$line" mp3/"$line".mp3 ; done
But I get this error::
$ ls *.ogg | while read line; do ffmpeg -i "$line" mp3/"$line".mp3 ; done
...
Parse error, at least 3 arguments were expected, only 0 given
in string ' 1 - 02 - À carreaux !.ogg' ...
...
This report bash ffmpeg find and spaces in filenames even if it look similar is for a more complicate script and has no answer.
This ffmpeg not working with filenames that have whitespace only fix it when output is a http:// URL
Upvotes: 1
Views: 312
Reputation: 42999
Use find -print0
to get the NUL-separated list of files, instead of parsing ls
output which is never a good idea:
#!/bin/bash
while read -d '' -r file; do
ffmpeg -i "$file" mp3/"$file".mp3 </dev/null
done < <(find . -type f -name '*.ogg' -print0)
You can use a simple glob to do this as well:
shopt -s nullglob # make glob expand to nothing in case there are no matching files
for file in *.ogg; do
ffmpeg -i "$file" mp3/"$file".mp3
done
See:
Upvotes: 6
Reputation: 530912
You don't need a loop here; let find
execute the command for you.
find . -type f -name '*.ogg' -exec ffmpeg -i {} mp3/{}.mp3 \;
Or, if you want to strip the .ogg
extension from the result:
find . -type f -name '*.ogg' -exec sh -c 'ffmpeg -i "$1" mp3/"${1%.ogg}.mp3"' _ {} \;
Conversely, you can skip find
altogether:
shopt -s extglob
for f in **/*.ogg; do
[[ -f $f ]] || continue
ffmpeg -i "$f" mp3/"${f%.ogg}.mp3"
done
Upvotes: 2