在for循环中像这样的:文件名不带扩展名在bash for循环
for f in `ls *.avi`; do echo $f; ffmpeg -i $f $f.mp3; done
$ F将是完整的文件名,包括扩展名。例如,对于song1.avi,命令的输出将是song1.avi.mp3。有没有办法只得到song1,没有for循环中的.avi?
我想有些方法可以使用awk或其他工具来实现,但我希望有更直接的方法。
感谢
在for循环中像这样的:文件名不带扩展名在bash for循环
for f in `ls *.avi`; do echo $f; ffmpeg -i $f $f.mp3; done
$ F将是完整的文件名,包括扩展名。例如,对于song1.avi,命令的输出将是song1.avi.mp3。有没有办法只得到song1,没有for循环中的.avi?
我想有些方法可以使用awk或其他工具来实现,但我希望有更直接的方法。
感谢
使用bash参数扩展
${f%%.*}
请注意,你需要贪婪的版本,因为有文件名多点。
从bash的手册:
$ {参数%字}
$ {参数%%字}
word被扩展,以产生一个模式,就像在文件名扩展。如果模式匹配参数扩展值的尾部分,则扩展结果是匹配模式最短的参数值('%'情况)或最长匹配模式('%%'情况)删除。如果参数是'@'或'',则将模式删除操作依次应用于每个位置参数,并且扩展是结果列表。如果参数是一个以'@'或''为下标的数组变量,则模式删除操作将依次应用于数组的每个成员,并且该扩展是结果列表。
使用'$ {f%。*}' - 如果您使用'$ {f %%。*}'而$ f是“one.two.avi”,您将得到“one”而不是“one”。两个“ –
这应做到:
for i in *.m4a; do
ffmpeg -i $i ${i%%.*}.mp3
done
对于一个已知的扩展(比如在'for'列表中),你可以使用'basename $ i .m4a'(反引号),但是一旦你记住'%。*'(百分之一,可以说更好),你不会再回头看。 –
由于缺乏引号,这有点bug。使它成为'ffmpeg -i“$ i”“$ {i %%。*}。mp3”'将修复对带有空格的文件名的支持。 (顺便说一句,这些是http://shellcheck.net/可以捕获的问题)。 –
顺便说一句,你不想失去反引号的无用使用。正确和习惯的语法是'for * in * .avi;做......' – tripleee
更不用说 - 如果你在文件名中有空格(尽管这是一种邪恶的做法),你实际上应该像'ls * avi |同时读f;做(...); done'。然后在每个地方引用'“$ f”'。只是说。 –