如何在shell脚本中获取文件的扩展名

13

我正在尝试从shell脚本中获取文件的扩展名,但是一直没有成功。

我使用的命令是

file_ext=${filename##*.}

file_ext = $filename |awk -F . '{if (NF>1) {print $NF}}'

但是这两个命令都未能将值放入变量file_ext中。但是当我尝试

echo $filename |awk -F . '{if (NF>1) {print $NF}}'

它给了我想要的结果,我对shell脚本很陌生,请描述一下发生了什么情况。也请告诉我该如何做?

谢谢。


更多参考资料,请访问http://tldp.org/LDP/abs/html/,这是一个非常好的地方! - Enrico Carlesso
我想知道为什么第一种样式有效。你能解释一下吗? - xiaohan2012
3个回答

25

要获取文件扩展名,只需使用shell

$ filename="myfile.ext"
$ echo ${filename##*.}
ext
$ file_ext=${filename##*.} #put to variable
$ echo ${file_ext}
ext

2
是的,但为什么这样能行?这个##*.是什么鬼东西? - Okonomiyaki3000
2
哈哈,@Okonomiyaki3000,Bash脚本对我来说大多数都是巫术XD。这个代码之所以有效,是因为{var##somepattern}是一个参数。##somepattern实际上从变量中删除了该模式,因此它删除了点之前的所有内容。这个方法的一个要点是,如果未找到该模式,则返回整个字符串(这可能是需要或不需要的,在我的情况下,当没有扩展名时,我想返回一个空字符串)。这里有一篇关于参数替换的好文章:https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html - verboze
谢谢!我以前不知道这个有用的功能! - Okonomiyaki3000
刚刚检查了一下,当文件名包含多个点时,这也可以正常工作。例如,filename="myfile.log.gz"将会返回gz,与预期相符。 - dav.garcia
更多的巫术在这里 - https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html(第2.6.2节 - 参数扩展)。 - Mohnish
如果文件是 tar.tar.gz,我们能否得到 tar.gz 而不是 gz - alper

14

空格是有害的。

无论如何,您应该做以下操作:

file_ext=$(echo $filename | awk -F . '{if (NF>1) {print $NF}}')

[编辑] Martin提供更好的建议:

file_ext=$(printf '%s' "$filename" | awk -F . '{if (NF>1) {print $NF}}')

这将把命令的输出存储在$file_ext中。


是的。这个想法是将命令放在$()中。感谢您的回答。 - vijay.shad
最好使用printf '%s' "$filename"而不是echo $filename。通过以下命令查看差异:touch -- -e '-e foo.txt\n\cbar.exe'; echo 'echoing all files:'; for f in *; do echo $f; done; echo 'printing all files:'; for f in *; do printf '%s\n' "$f"; done - Martin
awk 部分可以简化为 awk -F . 'NF > 1 {print $NF}' - Martin

3

在声明变量时,您需要小心。

variable1="string"    # assign a string value
variable3=`command`   # assign output from command
variable2=$(command)  # assign output from command

请注意,您不能在变量后面加空格,因为这会被解释为普通命令。


谢谢你的解释,我明白了,以后不会再犯这个错误了。 - vijay.shad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接