如何在bash中遍历指定目录下指定类型的所有文件
问题原因
你遇到的这个现象是bash通配符的默认行为导致的,常见有两类触发场景:
- 目标目录
/data/test/下不存在任何.csv后缀的文件,此时bash不会把*.csv当成通配符展开,而是直接把整个表达式作为普通字符串返回,所以循环只会执行一次,拿到的就是你看到的/data/test/*.csv这个无效路径。 - 你的脚本运行环境提前开启了
noglob选项(执行过set -f或者set -o noglob),该选项会禁用所有通配符展开功能,不管有没有匹配到文件,通配符都会被当成普通字符串处理。
修复方案
方案1(bash专属,推荐)
开启bash的nullglob选项,开启后如果通配符没有匹配到任何文件,会直接展开为空值,循环就不会执行,避免无效遍历:
WDIR=/data/test/ FTYPE=".csv" COUNT=1 # 开启nullglob shopt -s nullglob for FILE in "${WDIR}"/*"${FTYPE}"; do echo "##### Processing file # $COUNT: $FILE ######" # 你的业务逻辑 ((COUNT+=1)) done # 可选:如果脚本后续还有其他逻辑依赖默认通配符行为,用完可以关闭nullglob shopt -u nullglob
方案2(兼容POSIX sh,通用写法)
如果你需要脚本兼容更通用的POSIX shell,可以不用bash特有的选项,在循环开头加一层文件存在性判断,无效路径直接跳过即可:
WDIR=/data/test/ FTYPE=".csv" COUNT=1 for FILE in "${WDIR}"/*"${FTYPE}"; do # 判断当前路径是否为真实存在的普通文件,不是就跳过 [ -f "$FILE" ] || continue echo "##### Processing file # $COUNT: $FILE ######" # 你的业务逻辑 ((COUNT+=1)) done
额外验证步骤
如果确认目标目录下确实存在.csv文件还是出现该问题,可以在脚本开头加一行set +f关闭noglob选项,排除通配符被禁用的影响。
内容的提问来源于stack exchange,提问作者user149823
相关产品推荐
相关产品推荐

