ZSH:获取for循环的基名

ZSH: Get basename for for loop

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

所以这有效:

for i in *.flac;do ffmpeg -i $i -c:a libfdk_aac -vbr 3 $i.m4a; done

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

我想做的只是抓取文件名的 "audiofile" 部分,这样就可以了:

for i in *.flac;do ffmpeg -i $i.flac -c:a libfdk_aac -vbr 3 $i.m4a; done

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

有什么想法吗?

谢谢!

zsh中可以使用Modifiers from History Expansion with Parameter Expansions。每个修饰符前加一个冒号:${name:modifier}. Thermodifier 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

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

一个更便携的(阅读:应该在任何 POSIX-compliant shell 中工作)和具体的解决方案是使用 Parameter Expansion ${name%pattern},它会从name的值末尾移除匹配pattern的最小字符串。如果pattern没有匹配到name的值结尾,则返回值不变:

for i in *.flac; do
    ffmpeg -i $i -c:a libfdk_aac -vbr 3 ${i%.flac}.m4a
done

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