为何Bash Globbing搭配*与{..}时不生成不存在文件路径?
问题原因与解决方法
现象原因
单个目录场景
nameX_202410{01..30}.ext属于大括号展开操作,bash会先直接生成30个不含通配符的具体文件名,再将这些文件名全部传给ls。对于不存在的文件,ls会直接输出"文件不存在"的错误提示。
遍历目录场景
*/2024/10/*202410{01..30}.ext先通过大括号展开成30个带通配符的路径模式(比如*/2024/10/*20241001.ext)。bash对每个模式的处理逻辑分两种情况:
- 如果模式能匹配到至少一个实际文件,就把匹配到的路径列表传给
ls; - 如果模式完全匹配不到任何文件,若你的环境开启了
nullglob选项,bash会直接丢弃这个无匹配的模式,不会传给ls,因此不会出现错误提示;若未开启nullglob,bash会把模式字符串传给ls,但如果有其他模式匹配成功,错误提示可能被正常输出掩盖。
规避方法
1. 让遍历目录场景也显示未匹配提示
关闭nullglob(若开启)并开启failglob选项,强制bash在glob模式无匹配时直接报错,而非将模式传给ls:
shopt -u nullglob shopt -s failglob ls -al */2024/10/*202410{01..30}.ext
这样就能直观看到哪些日期的文件在所有目录下都不存在。
2. 让单个目录场景只显示存在的文件
开启nullglob选项,bash会自动丢弃所有无匹配的文件名(包括大括号展开后的无效文件名),只将存在的文件传给ls:
shopt -s nullglob ls -al nameX_202410{01..30}.ext
此时ls只会输出存在的文件,不会有错误提示。
3. 循环逐个检查(更可控)
如果需要精细记录不存在的文件,适合用循环遍历每个日期,逐个验证:
for day in {01..30}; do # 检查单个目录下的文件 single_file="nameX_202410${day}.ext" if [ -f "$single_file" ]; then ls -al "$single_file" else echo "不存在: $single_file" >&2 fi # 遍历所有目录检查对应文件 for glob_path in */2024/10/*_202410${day}.ext; do # 过滤掉未匹配的模式字符串(未开nullglob时) if [ -f "$glob_path" ]; then ls -al "$glob_path" else echo "不存在: $glob_path" >&2 fi done done
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

