在Bash中检查文件扩展名的最简单方法是什么?

37

我有一个 shell 脚本,如果文件是压缩的(以 .gz 结尾),我需要执行一个命令,如果不是,则执行另一个命令。我不太确定如何处理这个问题,以下是我正在寻找的大纲:

file=/path/name*

if [ CHECK FOR .gz ]
then echo "this file is zipped"
else echo "this file is not zipped"
fi

1
"zip != gzip",应该是“这个文件(未)被压缩为gzip格式”。 - jlliagre
1
正确的方法是使用文件。 - devnull
3个回答

63
您可以使用简单的正则表达式,在[[...]]测试中使用=~运算符来实现此操作:
if [[ $file =~ \.gz$ ]];

如果您关注的是扩展名为.tgz的情况,那么这并不能给您正确的答案。但很容易解决:

if [[ $file =~ \.t?gz$ ]];

缺少正则表达式周围的引号是必要且重要的。您可以引用$file,但没有意义。
最好使用file实用程序:
$ file --mime-type something.gz
something.gz: application/x-gzip

类似这样的:

if file --mime-type "$file" | grep -q gzip$; then
  echo "$file is gzipped"
else
  echo "$file is not gzipped"
fi

8
bash 中,你可以使用 if [[ $file = *.gz ]] 来代替正则表达式匹配。这种方法能够实现相同的功能,同时更加简洁易懂。 - chepner
1
@chepner,确实如此,但我想提供匹配.gz.tgz的模式。不可否认,你的代码稍微短一些。不过我认为使用file解决方案是更好的选择。 - rici

37

实际上,在shell脚本中匹配这种模式的最清晰、最简单的方法通常是使用case

case "$f" in
*.gz | *.tgz ) 
        # it's gzipped
        ;;
*)
        # it's not
        ;;
esac

是的,你说得对。在我看来,这是最干净的。 - Nishant
我实际上最喜欢这个。它是迄今为止最干净的。 - David Welborn

14

你可以尝试这样做:

if [[ ${file: -3} == ".gz" ]]

你应该使用[[或引用${file: -3};否则,如果$file的倒数第二个字符是空格,或者(可能)在最后三个字符中包含glob元字符,则会出现错误。 - rici
@rici:谢谢你的建议。我已经更新了我的答案!!:) - Rahul Tripathi
4
你也可以使用${file##*.} = gz,它适用于任何符合 POSIX 标准的 shell。 - chepner
[[ ... ]] 条件表达式中,扩展参数不会发生单词拆分,但是您对命名为 gz 的文件的误报是正确的。 - chepner
1
我想指出冒号后面的空格很重要。${var:-3}${var: -3}不同;第一个(没有空格)如果var未设置,则会扩展为“-3”,而第二个(有空格)返回var的最后3个字符。 - pbatey
显示剩余9条评论

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