For converting MOV files to mp4 in the directory, I was using (I use more commands with avconv, but I shortened for syntetize):
for f in *.MOV; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
And it works. It converts every file.
But now, I want to convert all the files in the directory and all subdirs (recursivelly). I tried:
for f in "$(find ./ -name '*.MOV')"; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
But it doesn't work, because it outputs:
mario@circo3d:~/Imágenes$ for f in "$(find ./ -name '*.MOV')"; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
Converting ./2015-05-23 Tutorial Masa de colores/MVI_9219.MOV
./2015-05-23 Tutorial Masa de colores/MVI_9196.MOV
./2015-05-23 Tutorial Masa de colores/MVI_9199.MOV
./2015-05-23 Tutorial Masa de colores/MVI_9200.MOV
avconv version 9.18-6:9.18-0ubuntu0.14.04.1, Copyright (c) 2000-2014 the Libav developers built on Mar 16 2015 13:19:10 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
./2015-05-23 Tutorial Masa de colores/MVI_9219.MOV
./2015-05-23 Tutorial Masa de colores/MVI_9196.MOV
./2015-05-23 Tutorial Masa de colores/MVI_9199.MOV
mario@circo3d:~/Imágenes$
(Last file list appear in red)
It seems that find works, it enters in every dir and echo "Converting $f" too... but avconv receives all that filenames as a list with newlines, not each one element from the "for" loop.
Why echo works and avconv doesn't?
Or...
Why for f in *.MOV' works with avconv and for f in "$(find ./ -name '*.MOV') doesn't?
This is because you put them in quotes. In POSIX a newline character can very well be present in the name of the file.
The easiest solution for you would be to rewrite using -exec
attribute of find:
find . -name "*.MTS" -exec echo {} \; -exec avconv -i {} {}.mp4 \;
Or even better, you could use -execdir
for the avconv
line, it will execute the command from the directory where the file is found.
From your comment i see that you are having difficulty seeing where the newlines are coming from at all. So
From man page of find:
If no expression is given, the expression -print is used
and
-print True; print the full file name on the standard output, followed
by a newline.
So find actually prints all the newline characters for you. You are calling it via $(find ...)
and then you place it in quotes, which means that all the newline characters are preserved as a regular character.
This is why your for loop executes only once.
If you absolutely must use a loop, rather than using find
's own execution, you probably want to use a while loop:
find . -name "*.MTS" | while read f; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done