为了将MOV文件转换为目录中的mp4,我正在使用(我在avconv中使用了更多命令,但我缩短了同步时间):
for f in *.MOV; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
它有效。它会转换每个文件。
但是现在,我想要转换目录和所有子目录中的所有文件(递归)。我试过了:
for f in "$(find ./ -name '*.MOV')"; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
但它不起作用,因为它输出:
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$
(上一个文件列表显示为红色)
似乎 find 有效,它进入每个目录并且回显“转换$ f” ...但是avconv将所有文件名作为带有换行符的列表接收,而不是“for”循环中的每一个元素。
为什么 echo 有效且 avconv 没有?
或者...
为什么 for * .MOV'适用于avconv而适用于“$(查找./ -name'* .MOV')中的f?
答案 0 :(得分:1)
这是因为你把它们放在引号中。在POSIX中,换行符很可能出现在文件名中。
最简单的解决方案是使用find:
的-exec
属性重写
find . -name "*.MTS" -exec echo {} \; -exec avconv -i {} {}.mp4 \;
甚至更好,您可以使用-execdir
作为avconv
行,它将从找到该文件的目录中执行命令。
根据您的评论,我发现您很难看到换行符的来源。所以
从find的手册页:
If no expression is given, the expression -print is used
和
-print True; print the full file name on the standard output, followed
by a newline.
因此,find实际上会为您打印所有换行符。您通过$(find ...)
调用它,然后将其放在引号中,这意味着所有换行符都保留为常规字符。
这就是你的for循环只执行一次的原因。
如果你绝对必须使用循环,而不是使用find
自己的执行,你可能想要使用while循环:
find . -name "*.MTS" | while read f; do echo "Converting $f"; avconv -i "$f" "${f:0: -4}.mp4"; done
答案 1 :(得分:0)
我用sox将mp3转换为alaw文件。非常相似的情况。使用简单的bash脚本。
#!/bin/bash
for file in $(find . -name '*.mp3')
do
echo $file
sox $file -t al -c 1 -r 8000 $(echo "$file" | sed -r 's|.mp3|.alaw|g')
done