通过AWS CLI同步S3存储桶到本地时重写路径的方法
解决S3同步时移除路径中的{version}文件夹问题
AWS CLI的s3 sync命令本身不支持同步过程中修改文件路径结构,不过可以通过AWS CLI结合脚本或者挂载S3后用本地工具处理两种方式实现需求,以下是具体方案:
方案一:AWS CLI + Shell脚本批量处理
这种方式直接调用AWS API,性能更稳定,适合大量文件同步:
- 创建同步脚本(比如
sync-s3-uploads.sh):
#!/bin/bash # 配置参数 BUCKET="your-bucket-name" LOCAL_TARGET="./wp-content/uploads" # 遍历S3桶中uploads目录下的所有文件 aws s3 ls s3://${BUCKET}/uploads/ --recursive | while read -r line; do # 提取文件的S3相对路径 FILE_PATH=$(echo "$line" | awk '{print $4}') [ -z "$FILE_PATH" ] && continue # 匹配路径结构:uploads/20**/**/{version}/file.* if [[ $FILE_PATH =~ ^uploads/([0-9]{4})/([0-9]{2})/([^/]+)/(.*)$ ]]; then YEAR=${BASH_REMATCH[1]} MONTH=${BASH_REMATCH[2]} FILENAME=${BASH_REMATCH[4]} # 构建本地目标路径(移除{version}层级) LOCAL_PATH="${LOCAL_TARGET}/${YEAR}/${MONTH}/${FILENAME}" # 创建本地目录(避免路径不存在报错) mkdir -p "$(dirname "$LOCAL_PATH")" # 执行复制 aws s3 cp "s3://${BUCKET}/${FILE_PATH}" "$LOCAL_PATH" fi done
- 给脚本添加执行权限:
chmod +x sync-s3-uploads.sh
- 定期执行:可以通过crontab设置定时任务,比如每天凌晨1点同步:
0 1 * * * /path/to/sync-s3-uploads.sh >> /var/log/s3-sync.log 2>&1
方案二:挂载S3桶后用本地工具处理
如果习惯用本地文件操作工具,可以用s3fs把S3桶挂载到本地,再处理路径:
- 安装并挂载S3桶:
# 安装s3fs(以Ubuntu为例) sudo apt install s3fs # 挂载S3桶到本地目录 s3fs your-bucket-name /mnt/s3-uploads
- 用
find+sed处理路径并复制:
LOCAL_TARGET="./wp-content/uploads" # 遍历挂载目录下的所有文件 find /mnt/s3-uploads/uploads -type f | while read -r s3_file; do # 提取S3相对路径 REL_PATH=${s3_file#/mnt/s3-uploads/} # 移除路径中的{version}层级 NEW_REL_PATH=$(echo "$REL_PATH" | sed -E 's|(uploads/[0-9]{4}/[0-9]{2})/[^/]+/(.*)|\1/\2|') # 构建本地路径并复制 LOCAL_PATH="${LOCAL_TARGET}/${NEW_REL_PATH}" mkdir -p "$(dirname "$LOCAL_PATH")" cp "$s3_file" "$LOCAL_PATH" done
注意事项
- 脚本中的正则表达式可根据实际
{version}的格式调整(比如如果version是固定前缀如v1.0,修改正则匹配规则即可) - 方案一的
aws s3 cp支持断点续传,适合大文件;方案二的s3fs性能略低,适合小批量文件同步 - 确保执行脚本的用户有足够的AWS权限(
s3:ListBucket和s3:GetObject)以及本地目录的读写权限
内容的提问来源于stack exchange,提问作者Schwipps
相关产品推荐
相关产品推荐

