wjd*_*jdp 6 command-line scripts find
尝试在大型音乐收藏中进行从 M4A 到 OGG 的大规模转换,我有:
#!/bin/sh
for i in `find /home/family/Music -name *.m4a -print0`
#do ffmpeg -i "$i" -acodec libvorbis -aq 6 -vn -ac 2 "$i.ogg";
do echo $i
done
Run Code Online (Sandbox Code Playgroud)
所有文件的名称中都会有空格,上面的输出显示了一个像这样的文件:
/home/family/Music/The
Kooks/Inside
In
_
Inside
Out/06
You
Don't
Love
Me.m4a
Run Code Online (Sandbox Code Playgroud)
每个空格都标记一个新行,我认为-print0
会解决这个问题吗?
ter*_*don 15
这就是为什么您从不使用for
循环来迭代输出可以包含空格的命令的原因之一。特别是如果该输出是一个文件名列表,其中可以包含除and之外的任何内容。您已陷入bash 陷阱 1。总是使用代替。要确保它适用于所有文件名,包括带有空格、换行符、制表符、反斜杠或任何其他奇怪字符的文件名,请使用以下命令:/
\0
while
find /home/family/Music -name '*.m4a' -print0 | while IFS= read -r -d '' file; do
ffmpeg -i "$file" -acodec libvorbis -aq 6 -vn -ac 2 "${file%.m4a}.ogg";
done
Run Code Online (Sandbox Code Playgroud)
请注意,我引用*.mp4a
了确保 bash 在将其传递给find
. 这对于在当前目录中有与该 glob 匹配的文件的情况很重要。
的-print0
,正如你可能知道,导致find
与分离的结果\0
,而不是换行。
IFS=
:这将输入字段字符设置为空,确保不会发生分词。
while read -r -d '' file
:这将迭代结果,将每个保存为$file
,就像for file in $(command)
. 选项是(来自help read
):
-r do not allow backslashes to escape any characters
-d delim continue until the first character of DELIM is read, rather
than newline
Run Code Online (Sandbox Code Playgroud)
将分隔符设置为空字符串 ( -d ''
) 可以read
很好地与 find 的-print0
.
"${file%.mp3}.ogg";
:这简直是去除.m4a
后缀,取而代之的是.ogg
让您得到foo.ogg
的不是foo.m4a.ogg
。
其余的与您尝试的相同,所以我猜您理解它。
使用xargs
with-0
选项,或使用find
自己的exec
选项:
find /home/family/Music -name '*.m4a' -exec ffmpeg -i "{}" -acodec libvorbis -aq 6 -vn -ac 2 "{}.ogg" \;
# or:
find /home/family/Music -name '*.m4a' -print0 | xargs -0 -i ffmpeg -i {} -acodec libvorbis -aq 6 -vn -ac 2 {}.ogg
Run Code Online (Sandbox Code Playgroud)
请注意,在这两种情况下(以及在您的原始命令中),x.m4a
都将转换为x.m4a.ogg
.
归档时间: |
|
查看次数: |
5167 次 |
最近记录: |