Shell脚本处理含空格文件名异常:identify无法识别完整文件
解决带空格文件名的Shell脚本处理问题
你的核心问题出在用for a in find...``遍历文件的方式——这种写法会把find输出的文件名按空格、制表符、换行符拆分,导致带空格的文件名被拆成多个片段,后续所有操作都会出错。
原代码的问题分析
- 循环遍历逻辑错误:
for a in $(find...)会将find结果按IFS(默认包含空格)拆分,比如name with spaces.jpg会被拆成name、with、spaces.jpg三个独立变量值,循环三次处理每个片段,自然触发identify找不到文件的报错。 - 冗余的路径拼接:
$a本身就是完整文件路径,没必要用$directory/$name拼接,多此一举还可能引入新的空格问题。 - 依赖
identify默认输出切割:默认输出格式可能随版本变化,用固定格式提取宽高更可靠。
正确解决方案
方案1:用find -exec直接处理(推荐)
利用find的-exec参数批量传递文件名,避免拆分问题:
find "$dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -exec sh -c ' for img do # 获取文件名和目录(如果需要的话) name=$(basename "$img") directory=$(dirname "$img") # 直接用identify指定格式输出宽高,避免切割默认输出 width=$(identify -format "%w" "$img") height=$(identify -format "%h" "$img") # 这里添加你的后续逻辑,比如打印结果 echo "文件: $name 宽度: $width 高度: $height" done ' sh {} +
方案2:用while read循环读取(处理特殊字符更安全)
如果需要处理包含换行符的极端文件名,用null字符分隔输出:
find "$dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | while IFS= read -r -d '' img; do name=$(basename "$img") width=$(identify -format "%w" "$img") height=$(identify -format "%h" "$img") echo "文件: $name 宽度: $width 高度: $height" done
关键优化点
- 避免用
for循环直接遍历find输出,改用-exec或while read处理带空格/特殊字符的文件名。 - 使用
identify -format "%w %h"直接提取宽高,比切割默认输出更稳定,无需多次调用cut。 - 所有变量引用都加双引号(如
"$img"、"$name"),防止空格拆分。
内容的提问来源于stack exchange,提问作者jpark
相关产品推荐
相关产品推荐

