Shell脚本检查文件存在:如何添加匹配name*.pdf的判断条件
通配文件存在性判断的修改方法
原脚本的判断逻辑是精确匹配指定单文件是否存在,要追加匹配name*.pdf这类通配文件的判断,核心是把两个判断条件用逻辑或关联,同时避开shell通配匹配的常见坑。
核心判断逻辑调整
只要满足任意一个条件,就执行通过分支:
- 原逻辑:精确匹配的
$FILE是存在的普通文件(-f "$FILE") - 新增逻辑:目录下存在至少一个匹配
name*.pdf规则的文件
避坑提醒
绝对不能直接把通配符塞到[ -f ]的测试条件里,比如写[ -f "name*.pdf" ]:
- 当没有匹配文件时,shell不会展开通配符,会把字面带星号的字符串当成文件名做判断,永远匹配不到真实文件
- 当存在多个匹配文件时,会因为传入参数过多触发测试命令报错,完全不符合预期
可直接复用的实现代码
兼容POSIX shell的通用写法
这种写法不需要依赖bash专属特性,所有默认shell都能运行,通过重定向ls的输出来判断是否有匹配文件:
if [ -f "$FILE" ] || ls name*.pdf >/dev/null 2>&1; then echo "OK $f" else echo "!!! Not OK $f" fi
代码说明:
- 前面的
[ -f "$FILE" ]完全保留原脚本的单文件判断能力 - 后面的
ls name*.pdf >/dev/null 2>&1会触发shell自动展开通配规则:只要有1个以上匹配的pdf文件,ls就会返回成功状态,输出全部重定向到空设备不会干扰正常日志;没有任何匹配文件时ls会返回失败状态,整个判断不成立。
Bash专属的严谨写法
如果确定脚本运行环境是bash,可以用空glob设置+数组计数的写法,避免文件名带空格、特殊符号时ls判断失效的问题:
# 开启空glob规则:无匹配文件时通配结果为空,不会保留字面星号 shopt -s nullglob # 把所有匹配的文件存入数组 matched_pdfs=( name*.pdf ) if [ -f "$FILE" ] || [ ${#matched_pdfs[@]} -gt 0 ]; then echo "OK $f" else echo "!!! Not OK $f" fi
动态生成通配规则的写法
如果不需要硬编码name*.pdf,而是要基于原$FILE的值自动生成同前缀的通配规则(比如$FILE是report.pdf,自动匹配report*.pdf),可以用字符串截取动态生成匹配模式:
# 动态生成通配规则:保留原文件的前缀和后缀,中间替换为* glob_pattern="${FILE%.*}*.${FILE##*.}" # 注意:这里的glob_pattern不要加引号,否则shell不会执行通配展开导致判断失效 if [ -f "$FILE" ] || ls $glob_pattern >/dev/null 2>&1; then echo "OK $f" else echo "!!! Not OK $f" fi
内容的提问来源于stack exchange,提问作者Elena Greg
相关产品推荐
相关产品推荐

