如何修改脚本避免将含空格的文件视为独立文件?
解决带空格文件名的脚本修改方案
嘿,这个问题我太熟了!你的脚本处理带空格的文件名时出错,核心原因是**for i in $(find ...)这种写法会让shell把文件名按空格拆分**——比如Axle Assy Removal.doc会被拆成三个独立的“文件”,mv自然找不到这些被拆分的片段啦。
下面给你两个靠谱的修改方案,任选其一就行:
方案一:用find的-exec选项(最推荐)
这种方式是处理带特殊字符文件名的标准做法,find会直接把完整的文件名传递给命令,完全不会拆分。修改后的脚本如下:
thetime=$(date +%Y-%m-%d_%H:%M:%S) # 只处理文件(如果需要处理目录可以去掉-type f) find . ! -name "*.filepart" -type f -exec sh -c ' for i do extn=${i##*.} # 给文件名加上统一的时间戳后缀 mv "$i" "${i%.*}_'"$thetime"'.${extn}" done ' sh {} +
简单解释:
find ... -exec sh -c '...' sh {} +:find会把所有匹配到的文件作为参数传给后面的sh脚本,for i do会逐个遍历这些完整的文件名(包括空格)- 把
thetime变量嵌入到sh脚本里,确保所有文件用同一个时间戳,避免循环中多次调用date导致时间不一致
方案二:修改IFS字段分隔符(适合坚持用for循环的场景)
如果你一定要保留for循环的结构,可以通过修改shell的内部字段分隔符(IFS),让它只按换行符拆分内容,而不是空格/制表符。脚本如下:
thetime=$(date +%Y-%m-%d_%H:%M:%S) # 先保存原来的IFS,避免影响后续命令 OLD_IFS="$IFS" # 设置IFS为换行符,让shell只按行拆分find的输出 IFS=$'\n' # 加上-type f只处理文件,避免误操作目录 for i in $(find . ! -name "*.filepart" -type f) do extn=${i##*.} mv "$i" "${i%.*}_${thetime}.${extn}" done # 恢复原来的IFS IFS="$OLD_IFS"
注意事项:
- 一定要记得恢复原来的IFS,否则后续的shell命令可能会因为字段分隔符改变而出错
- 这种方式虽然可行,但如果文件名里包含换行符(虽然极少见)还是会出问题,所以方案一更稳妥
内容的提问来源于stack exchange,提问作者JT-66
相关产品推荐
相关产品推荐

