如何将S3存储桶单文件夹内大量文件均匀拆分移动到多个文件夹
解决方案
改进后的Python实现方案
思路:遍历源文件夹下所有对象,按计数切换目标存储路径,每移动750万个文件就切换到下一个目标文件夹,同存储桶内复制无需本地中转,完成复制后删除源文件实现mv效果。
import boto3 # 建议通过环境变量、IAM角色或~/.aws/credentials配置凭证,不要硬编码 s3 = boto3.resource('s3') bucket_name = "你的存储桶名称" src_prefix = "myfolder/" target_prefixes = ["folder1/", "folder2/", "folder3/", "folder4/"] file_per_folder = 7500000 bucket = s3.Bucket(bucket_name) current_target_idx = 0 count = 0 def move_files(): global current_target_idx, count for obj in bucket.objects.filter(Prefix=src_prefix): # 跳过文件夹本身的标记对象(如果存在) if obj.key == src_prefix: continue # 满750万切换下一个目标文件夹 if count >= file_per_folder: current_target_idx += 1 count = 0 # 生成目标key,替换源前缀为目标前缀 target_key = obj.key.replace(src_prefix, target_prefixes[current_target_idx], 1) # 同桶复制 s3.meta.client.copy_object( Bucket=bucket_name, CopySource={'Bucket': bucket_name, 'Key': obj.key}, Key=target_key, ACL='public-read' # 不需要该权限可删除 ) # 删除源文件,等效于mv操作 obj.delete() count += 1 if __name__ == "__main__": move_files()
注意事项
- 若脚本中途中断,可记录最后一次处理的对象key,下次调用
bucket.objects.filter(Prefix=src_prefix, Marker='最后处理的key')来续跑,避免重复处理 - 同存储桶内copy_object操作不会产生外网流量,仅会产生少量的API请求费用
- 如果不需要保留源文件的public-read ACL,可以去掉ACL参数,继承目标存储桶的权限配置
- 3000万文件遍历耗时较长,建议在AWS同区域的ECS/EC2实例上运行脚本,减少网络延迟
CLI简易方案(不推荐3000万文件大场景使用)
小批量场景不想写代码的话,可通过管道分批处理:
- 分批导出文件列表
aws s3api list-objects-v2 --bucket BUCKETNAME --prefix myfolder/ --query 'Contents[].Key' --output text | xargs -n 7500000 | split -l 1 -a 1 -d - file_batch_
- 逐批移动文件,以第一批为例:
cat file_batch_0 | xargs -I {} aws s3 mv s3://BUCKETNAME/{} s3://BUCKETNAME/folder1/${{}#myfolder/}
该方案处理超大量文件时list操作耗时久、容错率低,优先推荐Python方案。
内容的提问来源于stack exchange,提问作者Karthik
相关产品推荐
相关产品推荐

