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)的完整实现示例:
✅
关键说明
:
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 “显式优于隐式”设计哲学的体现。
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.")
}