ZSH:获取 for 循环的基名

ran*_*vel 1 for-loop zsh

我正在尝试获取基本名称(没有文件扩展名),以便我可以使用正确的文件名快速处理音频文件目录(.flac -> .m4a)。

所以这有效:

for i in *.flac;do ffmpeg -i $i -c:a libfdk_aac -vbr 3 $i.m4a; done
Run Code Online (Sandbox Code Playgroud)

但它给我留下了这样的文件:audiofile.flac.m4a

我想要做的只是获取文件名的“音频文件”部分,这样就可以了:

for i in *.flac;do ffmpeg -i $i.flac -c:a libfdk_aac -vbr 3 $i.m4a; done
Run Code Online (Sandbox Code Playgroud)

但我不理解修饰符(显然“:t”修饰符可能会给我结果?)或如何在 for 循环上定义变量(对于每个文件)。另外,我看到有很多关于如何使用 BASH 执行此操作的示例,但我正在寻找适用于 zsh 的东西。

有任何想法吗?

谢谢!

Ada*_*hon 6

zsh你可以使用修改器历史扩展参数扩展。每个修饰符前面都有一个冒号:${name:modifier}. Ther modifier removes the extension, i.e. everything from - including - the last.` 到文件名的末尾:

for i in *.flac; do 
    ffmpeg -i $i -c:a libfdk_aac -vbr 3 ${i:r}.m4a
done
Run Code Online (Sandbox Code Playgroud)

注意:修饰符r将删除任何扩展名,而不仅仅是“.flac”。

更便携(阅读:应该在任何符合 POSIX 的 shell 中工作)和特定的解决方案是使用Parameter Expansion ${name%pattern},它将patternname. 如果pattern不匹配 的值的结尾,则name该值将原样返回:

for i in *.flac; do
    ffmpeg -i $i -c:a libfdk_aac -vbr 3 ${i%.flac}.m4a
done
Run Code Online (Sandbox Code Playgroud)

这将仅从文件名的末尾删除“.flac”。