Bash中用通配符检查特定扩展名文件存在性及代码问题排查
问题分析与解决方法
你的代码出错的原因
- 当目录下存在多个
.dat文件时,DAT=/project/abc/outboud/*.dat会被Shell自动展开成多个文件名用空格分隔的字符串(比如/project/abc/outboud/a.dat /project/abc/outboud/b.dat),此时[[ -f $DAT ]]会尝试判断这个多文件名组合是否是单个文件,显然不成立,条件直接为假。 - 如果目录下没有
.dat文件,通配符不会自动展开,$DAT的值就是原始字符串/project/abc/outboud/*.dat,这个文件本身不存在,-f的判断自然也不成立。
另外你代码里的else直接输出"TXT files"逻辑也有问题——实际场景中可能同时存在两种文件,或者两种都不存在,不能简单用非此即彼的判断。
正确的实现方式
方法1:数组+nullglob选项(推荐)
开启nullglob选项可以让通配符匹配不到文件时返回空值(而非保留原始通配符字符串),再用数组存储匹配结果,通过数组长度判断是否存在对应文件:
# 开启nullglob,避免无匹配时保留通配符字符串 shopt -s nullglob # 将所有.dat文件存入数组 dat_files=(/project/abc/outboud/*.dat) # 将所有.txt文件存入数组 txt_files=(/project/abc/outboud/*.txt) # 检查是否存在.dat文件 if [[ ${#dat_files[@]} -gt 0 ]]; then echo "DAT files exist" fi # 检查是否存在.txt文件 if [[ ${#txt_files[@]} -gt 0 ]]; then echo "TXT files exist" fi # 可选:用完后关闭nullglob(如果后续不需要该特性) shopt -u nullglob
方法2:用ls命令快速判断(简单但不推荐特殊文件名场景)
如果只是快速验证是否存在对应文件,可以借助ls命令,将匹配不到时的错误输出丢弃,通过命令返回值判断:
# 检查.dat文件 if ls /project/abc/outboud/*.dat >/dev/null 2>&1; then echo "DAT files exist" fi # 检查.txt文件 if ls /project/abc/outboud/*.txt >/dev/null 2>&1; then echo "TXT files exist" fi
注意:这种方法在文件名包含空格、特殊字符时可能出现异常,优先推荐数组方案。
内容的提问来源于stack exchange,提问作者Liu Yu
相关产品推荐
相关产品推荐

