Shell脚本如何读取含空格的完整文件名避免被拆分
问题根源
脚本出现文件名被空格拆分的核心原因有两个:
- 反引号
`捕获命令输出后,shell会默认以空格、制表符、换行这类空白字符为分隔符拆分内容,拆分后的每个片段都会被单独作为for循环的迭代项,因此A B C.jpg去掉后缀后的A B C会被拆成A、B、C三个独立值 - 禁止解析
ls输出来遍历文件是shell脚本编写的基本准则,这种写法除了会拆分带空格的文件名,遇到包含换行、通配符等特殊字符的文件名时也会出现逻辑异常。
兼容dash的正确实现
不需要依赖ls、grep、sed这类外部命令,用dash原生支持的POSIX标准语法即可,完全支持带空格、特殊字符的文件名:
#!/bin/dash for file in ./*.jpg; do # 无jpg文件时跳过,避免通配符匹配失败输出*.jpg字面量 [ -e "$file" ] || continue # 移除.jpg后缀 name="${file%.jpg}" # 移除路径前缀./ name="${name#./}" echo "$name" done
语法说明
- 直接用
./*.jpg通配符遍历当前目录下的jpg文件是POSIX标准规定的行为,所有兼容POSIX的shell(包括dash)都支持,遍历过程中不会按空格拆分文件名,每个文件会被作为独立的完整值传入循环 - 所有变量引用都用双引号包裹,避免变量值内的空白字符被shell二次拆分
- 用
${var%pattern}、${var#pattern}的原生参数扩展完成后缀、前缀移除,不需要调用外部命令,执行效率更高,也不存在特殊字符转义问题 - 增加文件存在判断是为了兼容当前目录没有jpg文件的边界场景,避免通配符匹配失败时把
*.jpg字符串当成文件名输出。
内容的提问来源于stack exchange,提问作者Allen_sHH
相关产品推荐
相关产品推荐

