如何编写Bash脚本实现跨根目录按原路径递归复制HTML文件
实现方案
不需要依赖pwd做路径提取,也不需要写复杂逻辑,单行命令即可完成需求,也可以封装成易维护的脚本版本。
单行直接执行命令
带自动创建目标目录功能(推荐)
直接在项目根目录执行即可,递归遍历所有html文件,自动补全不存在的目标文件夹,同名文件直接覆盖:
find ./tmp/serve -type f -name "*.html" -exec bash -c 'mkdir -p ./src/$(dirname "${1#./tmp/serve/}") && cp "$1" "./src/${1#./tmp/serve/}"' _ {} \;
仅复制(不自动建目录)
如果你确认目标路径的文件夹已经全部提前创建,可以用更短的版本:
find ./tmp/serve -type f -name "*.html" -exec bash -c 'cp "$1" "./src/${1#./tmp/serve/}"' _ {} \;
命令逻辑说明
find ./tmp/serve -type f -name "*.html":递归查找./tmp/serve目录下所有后缀为.html的普通文件,跳过目录、链接等其他类型文件${1#./tmp/serve/}:Bash内置字符串截取语法,去掉文件路径中./tmp/serve/的前缀,得到文件相对于源根目录的路径,比如./tmp/serve/app/components/help/help.html处理后得到app/components/help/help.htmlmkdir -p:递归创建目标文件的父目录,已存在的目录不会触发报错,不需要提前手动建文件夹- 整个写法兼容带空格、特殊字符的文件名,不会出现路径截断问题。
可维护脚本版本
如果需要频繁修改路径或者加后续逻辑,可以写成独立bash脚本:
- 新建
copy_html.sh文件,写入以下内容:
#!/bin/bash # 源目录和目标目录配置,后续改路径直接改这两个变量即可 SRC_ROOT="./tmp/serve" DEST_ROOT="./src" find "$SRC_ROOT" -type f -name "*.html" | while read -r html_file; do # 提取相对路径 relative_path="${html_file#$SRC_ROOT/}" # 拼接目标文件全路径 dest_file="$DEST_ROOT/$relative_path" # 自动创建父目录,不需要可以注释下行 mkdir -p "$(dirname "$dest_file")" # 执行复制 cp "$html_file" "$dest_file" done
- 给脚本加执行权限:
chmod +x copy_html.sh
- 在项目根目录执行脚本:
./copy_html.sh
补充说明
你之前写的echo $(find . -name "*.html")存在两个问题:一是会把所有文件路径拼接成单行输出,二是遇到带空格的文件名会错误拆分,不适合直接用于后续复制逻辑,用上述find -exec或者while read的写法更稳妥。
内容的提问来源于stack exchange,提问作者tanilLemon
相关产品推荐
相关产品推荐

