如何批量替换匹配目录名称中的指定字符串并排除指定目录?
批量替换目录名的Bash脚本实现(带排除目录功能)
直接给你能用的脚本,然后一步步拆解开讲,保证新手也能看懂:
#!/bin/bash # 要替换的旧关键词 OLD_STR="components" # 替换后的新关键词 NEW_STR="materials" # 要排除的目录(多目录的话看后面的扩展说明) EXCLUDE_DIR="./node_modules" # 核心逻辑:遍历目录→排除指定路径→先处理深层目录→批量重命名 find . -type d -path "$EXCLUDE_DIR" -prune -o -name "*$OLD_STR*" -print0 | sort -rz | while IFS= read -r -d '' dir; do # 生成替换后的新目录路径 new_dir="${dir//$OLD_STR/$NEW_STR}" # 执行重命名,-v参数会显示操作过程 mv -v "$dir" "$new_dir" done
脚本每个部分拆解得明明白白
1. 基础变量设置
OLD_STR="components":你要从目录名里换掉的旧字符串,直接改这里就能适配其他替换需求NEW_STR="materials":替换后的目标字符串,同理可改EXCLUDE_DIR="./node_modules":指定不用遍历的目录,避免误改依赖包
2. find命令:精准遍历+过滤
find . -type d -path "$EXCLUDE_DIR" -prune -o -name "*$OLD_STR*" -print0
.:从当前目录开始往下搜-type d:只找目录,不碰文件(避免误改文件名)-path "$EXCLUDE_DIR" -prune:遇到指定的排除目录,直接跳过整个分支,不往下遍历-o:逻辑“或”——前面的排除条件不满足时,执行后面的匹配操作-name "*$OLD_STR*":只挑名称里包含components的目录-print0:用空字符分隔搜索结果,避免目录名带空格、特殊字符时出错
3. sort -rz:先改深层目录
sort -rz
-r:反向排序,让深层目录排在前面(比如先改src/components/button,再改src/components),要是先改父目录,子目录的路径就失效了,这步很关键-z:配合前面的-print0,按空字符分割的内容排序,兼容特殊目录名
4. 循环处理每个目录
while IFS= read -r -d '' dir; do ... done
IFS=:防止目录名开头/结尾的空格被吃掉read -r:原样读取路径,不转义特殊字符(比如!、$这类)-d '':按空字符作为分隔符,对应前面的-print0,保证带空格的目录名能被正确读取
5. 重命名操作
new_dir="${dir//$OLD_STR/$NEW_STR}":Bash自带的字符串替换语法,把目录路径里所有的components替换成materialsmv -v "$dir" "$new_dir":执行重命名,-v会显示每一步的操作(比如renamed './src/available-components' -> './src/available-materials'),方便你确认没改错
怎么用这个脚本
- 把上面的代码复制到文本编辑器,保存成
rename_dirs.sh - 打开终端,给脚本加执行权限:
chmod +x rename_dirs.sh - 切换到你要操作的项目根目录(比如
cd ~/my-project) - 运行脚本:
./rename_dirs.sh
额外扩展说明
- 如果要排除多个目录,修改find命令的排除部分就行,比如要跳过
node_modules、dist、.git:
注意括号前后必须加空格,不然会报错find . -type d \( -path "./node_modules" -o -path "./dist" -o -path "./.git" \) -prune -o -name "*$OLD_STR*" -print0 - 建议先在测试目录里跑一遍,确认没问题再用到正式项目里,避免误改
内容的提问来源于stack exchange,提问作者sorin182004
相关产品推荐
相关产品推荐

