跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何在 Go 中使用前缀匹配批量删除 Amazon S3 对象

Amazon S3 不支持通配符(如 x/y/*)直接删除对象,但可通过 ListObjectsV2 + 分批 DeleteObjects 实现前缀匹配的批量删除;Go SDK 需手动实现分页列举与 1000 个/批的删除逻辑。 amazon s3 不支持通配符(如 `x/y/*`)直接删除对象,但可通过 listobjectsv2 + 分批 deleteobjects 实现前缀匹配的批量删除;go sdk 需手动实现分页列举与 1000 个/批的删除逻辑。 在 Go 中使用 AWS SDK for Go(v1 或 v2)删除指定前缀下的所有 S3 对象,本质是两步操作: 先列举(list)所有匹配前缀的键(Keys),再分批提交 DeleteObjects 请求 。S3 本身不支持正则或通配符语法(如 "x/y/.*" 在 DeleteObjectsInput 中无效),Key 字段仅接受精确字符串;因此必须依赖 ListObjectsV2 的 Prefix 参数进行前缀过滤。 以下是基于 AWS SDK for Go v1 (github.com/aws/aws-sdk-go)的完整实现示例:
package main import ( "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3manager" ) func deleteObjectsByPrefix(svc *s3.S3, bucket, prefix string) error { var keysToDelete []*s3.ObjectIdentifier // 分页列举所有匹配 prefix 的对象 params := &s3.ListObjectsV2Input{ Bucket: aws.String(bucket), Prefix: aws.String(prefix), } err := svc.ListObjectsV2Pages(params, func(page *s3.ListObjectsV2Output, lastPage bool) bool { for _, obj := range page.Contents { keysToDelete = append(keysToDelete, &s3.ObjectIdentifier{ Key: obj.Key, }) } return true // 继续下一页 }) if err != nil { return fmt.Errorf("failed to list objects: %w", err) } // 批量删除:每批最多 1000 个对象 const batchSize = 1000 for i := 0; i < len(keysToDelete); i += batchSize { end := i + batchSize if end > len(keysToDelete) { end = len(keysToDelete) } batch := keysToDelete[i:end] deleteParams := &s3.DeleteObjectsInput{ Bucket: aws.String(bucket), Delete: &s3.Delete{ Objects: batch, Quiet: aws.Bool(true), // 减少响应体大小(可选) }, } _, err := svc.DeleteObjects(deleteParams) if err != nil { return fmt.Errorf("failed to delete batch starting at %d: %w", i, err) } fmt.Printf("Deleted %d objects (batch %d–%d)\n", len(batch), i, end-1) } return nil } func main() { sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: &session.SharedConfigState{Config: aws.Config{ Region: aws.String("us-east-1"), }}, })) svc := s3.New(sess) err := deleteObjectsByPrefix(svc, "my-bucket", "x/y/") if err != nil { panic(err) } fmt.Println("All objects under 'x/y/' deleted successfully.") }
✅ 关键说明 : Amazon Nova 亚马逊云科技(AWS)推出的一系列生成式AI基础模型 下载 Prefix: aws.String("x/y/") 是核心——它等效于“伪文件夹”匹配(S3 无真实目录结构,仅靠 / 分隔键名); ListObjectsV2Pages 自动处理分页(含 ContinuationToken),避免手动循环; DeleteObjects 单次最多接受 1000 个对象 ,务必分批调用,否则返回 InvalidArgument 错误; 若需更高可靠性,可在 DeleteObjects 后检查 DeleteObjectsOutput.Deleted 和 Errors 字段,对失败项重试; 使用 SDK v2?只需替换导入路径(github.com/aws/aws-sdk-go-v2/service/s3)并调整客户端初始化方式,核心逻辑完全一致。 ⚠️ 注意事项 : 删除不可逆,请在生产环境前用 ListObjectsV2 预览待删对象(例如加 fmt.Println(*obj.Key) 调试); 大量对象(如百万级)建议配合 --dry-run 标志或先写入日志再执行; 权限需包含 s3:ListBucket 和 s3:DeleteObject(若跨前缀还需 s3:ListBucket 的 Prefix 权限限制); 如需删除带版本的对象,应改用 ListObjectVersions + DeleteObjects 并设置 VersionId。 该方案已广泛用于 Go 生态的 S3 清理工具(如 s3rm、自研 CI/CD 清理脚本),稳定可靠。虽无开箱即用的 DeleteAllObjects 方法,但 30 行核心逻辑即可复刻 PHP SDK 的能力——这也是云服务 SDK “显式优于隐式”设计哲学的体现。

相关文章