Bash脚本:判断gzip压缩文件的两种方式哪个更优?
判断gzip文件的两种Shell写法对比及疑问解答
问题背景
我需要判断某个文件是否为gzip压缩格式,但存在他人移除.gz后缀的情况,因此不能通过文件名后缀判断,改用file $filename命令来识别文件类型。该命令的输出示例如下:
zip1.gz: gzip compressed data, was "zip1", from Unix, last modified: Fri Jan 26 11:01:59 2024
目前有两种看似都可行的判断命令:
# 写法一 if file $filename | grep -q gzip ; then # 你的处理逻辑 fi # 写法二 if [[ $(file $filename) == *"gzip"* ]] ; then # 你的处理逻辑 fi
哪种方式更推荐?
优先选择写法一,理由如下:
- 性能更高:
grep -q是静默匹配模式,只要在file的输出里找到"gzip"就会立刻退出,不用等待file输出全部内容;而写法二需要先把file的完整输出捕获到子shell的结果里,再做通配匹配,输出内容越长,效率差距越明显。 - 兼容性更强:
[[ ... ]]是Bash的扩展语法,在Dash这类遵循POSIX标准的轻量Shell里无法运行;而管道+grep的写法是完全符合POSIX标准的,能在绝大多数Shell环境下正常工作。 - 更符合Unix设计理念:用小工具组合完成任务是Unix的核心思想,管道写法的可读性和维护性都更好,熟悉Shell的人一眼就能看懂逻辑。
为什么写法一可行?
你之前对grep的理解有误——grep默认并不是只能读取文件,它的输入来源是标准输入(stdin)。管道|的作用就是把前一个命令的标准输出,直接传递给后一个命令的标准输入。
具体流程是:file $filename把文件类型信息输出到标准输出,管道将这个输出流导向grep的标准输入,grep从这个输入流里查找包含"gzip"的行,找到就返回0(对应Shell里的true),没找到返回非0(false),刚好能作为if语句的判断条件。
内容的提问来源于stack exchange,提问作者jktstance
相关产品推荐
相关产品推荐

