是否有可能将所有文件从一个S3存储桶复制到另一个s3cmd?

我对s3cmd非常满意,但有一个问题:如何将所有文件从一个S3存储桶复制到另一个存储区? 这甚至有可能吗?

编辑:我已经find一种方法来使用Python与boto之间的桶之间复制文件:

from boto.s3.connection import S3Connection def copyBucket(srcBucketName, dstBucketName, maxKeys = 100): conn = S3Connection(awsAccessKey, awsSecretKey) srcBucket = conn.get_bucket(srcBucketName); dstBucket = conn.get_bucket(dstBucketName); resultMarker = '' while True: keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker) for k in keys: print 'Copying ' + k.key + ' from ' + srcBucketName + ' to ' + dstBucketName t0 = time.clock() dstBucket.copy_key(k.key, srcBucketName, k.key) print time.clock() - t0, ' seconds' if len(keys) < maxKeys: print 'Done' break resultMarker = keys[maxKeys - 1].key 

同步与复制几乎一样简单。 有ETag字段,大小和最后修改键可用。

也许这也有助于其他人。

s3cmd sync s3://from/this/bucket/ s3://to/this/bucket/

有关可用选项,请使用: $s3cmd --help

AWS CLI似乎完美地完成了这项工作,并且获得了官方支持的工具奖金。

 aws s3 sync s3://mybucket s3://backup-mybucket 

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

当我写这篇文章的时候,最赞成的答案是这样的:

 s3cmd sync s3://from/this/bucket s3://to/this/bucket 

这是一个有用的答案。 但有时同步不是你需要的(它删除文件等)。 我花了很长时间才发现这个非脚本化的替代scheme只是在桶之间复制多个文件。 (好吧,如下所示,它不在桶之间,而是在非真正的文件夹之间,但它同样适用于桶之间)。

 # Slightly verbose, slightly unintuitive, very useful: s3cmd cp --recursive --exclude=* --include=file_prefix* s3://semarchy-inc/source1/ s3://semarchy-inc/target/ 

上述命令的解释:

  • -recursive
    在我看来,我的要求是不recursion的。 我只是想要多个文件。 但是在这个上下文中recursion只是告诉s3cmd cp来处理多个文件。 大。
  • -排除
    想想这个问题是一种奇怪的方式。 开始recursionselect所有文件。 接下来,排除所有文件。 等等,什么?
  • -包括
    现在我们在说话。 指出要包含的文件前缀(或后缀或任何模式)。
    s3://sourceBucket/ s3://targetBucket/
    这部分足够直观。 尽pipe在技术上它似乎违反了s3cmd帮助文档中的示例,该示例指示必须指定源对象:
    s3cmd cp s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]

我需要复制一个非常大的桶,所以我把这个问题中的代码调整为一个multithreading版本,并把它放在GitHub上。

https://github.com/paultuckey/s3-bucket-to-bucket-copy-py

这实际上是可能的。 这对我工作:

 import boto AWS_ACCESS_KEY = 'Your access key' AWS_SECRET_KEY = 'Your secret key' conn = boto.s3.connection.S3Connection(AWS_ACCESS_KEY, AWS_SECRET_KEY) bucket = boto.s3.bucket.Bucket(conn, SRC_BUCKET_NAME) for item in bucket: # Note: here you can put also a path inside the DEST_BUCKET_NAME, # if you want your item to be stored inside a folder, like this: # bucket.copy(DEST_BUCKET_NAME, '%s/%s' % (folder_name, item.key)) bucket.copy(DEST_BUCKET_NAME, item.key) 

您也可以使用Web界面来执行此操作:

  1. 转到Web界面中的源桶。
  2. 标记您要复制的文件(使用移位和鼠标点击标记几个)。
  3. 按操作 – >复制。
  4. 转到目标存储分区。
  5. 按操作 – >粘贴。

而已。

谢谢 – 我使用稍微修改的版本,其中我只复制不存在或不同大小的文件,并检查目标是否存在于源中。 我发现这个testing环境更快一些:

 def botoSyncPath(path): """ Sync keys in specified path from source bucket to target bucket. """ try: conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) srcBucket = conn.get_bucket(AWS_SRC_BUCKET) destBucket = conn.get_bucket(AWS_DEST_BUCKET) for key in srcBucket.list(path): destKey = destBucket.get_key(key.name) if not destKey or destKey.size != key.size: key.copy(AWS_DEST_BUCKET, key.name) for key in destBucket.list(path): srcKey = srcBucket.get_key(key.name) if not srcKey: key.delete() except: return False return True 

我写了一个备份S3存储桶的脚本: https : //github.com/roseperrone/aws-backup-rake-task

 #!/usr/bin/env python from boto.s3.connection import S3Connection import re import datetime import sys import time def main(): s3_ID = sys.argv[1] s3_key = sys.argv[2] src_bucket_name = sys.argv[3] num_backup_buckets = sys.argv[4] connection = S3Connection(s3_ID, s3_key) delete_oldest_backup_buckets(connection, num_backup_buckets) backup(connection, src_bucket_name) def delete_oldest_backup_buckets(connection, num_backup_buckets): """Deletes the oldest backup buckets such that only the newest NUM_BACKUP_BUCKETS - 1 buckets remain.""" buckets = connection.get_all_buckets() # returns a list of bucket objects num_buckets = len(buckets) backup_bucket_names = [] for bucket in buckets: if (re.search('backup-' + r'\d{4}-\d{2}-\d{2}' , bucket.name)): backup_bucket_names.append(bucket.name) backup_bucket_names.sort(key=lambda x: datetime.datetime.strptime(x[len('backup-'):17], '%Y-%m-%d').date()) # The buckets are sorted latest to earliest, so we want to keep the last NUM_BACKUP_BUCKETS - 1 delete = len(backup_bucket_names) - (int(num_backup_buckets) - 1) if delete <= 0: return for i in range(0, delete): print 'Deleting the backup bucket, ' + backup_bucket_names[i] connection.delete_bucket(backup_bucket_names[i]) def backup(connection, src_bucket_name): now = datetime.datetime.now() # the month and day must be zero-filled new_backup_bucket_name = 'backup-' + str('%02d' % now.year) + '-' + str('%02d' % now.month) + '-' + str(now.day); print "Creating new bucket " + new_backup_bucket_name new_backup_bucket = connection.create_bucket(new_backup_bucket_name) copy_bucket(src_bucket_name, new_backup_bucket_name, connection) def copy_bucket(src_bucket_name, dst_bucket_name, connection, maximum_keys = 100): src_bucket = connection.get_bucket(src_bucket_name); dst_bucket = connection.get_bucket(dst_bucket_name); result_marker = '' while True: keys = src_bucket.get_all_keys(max_keys = maximum_keys, marker = result_marker) for k in keys: print 'Copying ' + k.key + ' from ' + src_bucket_name + ' to ' + dst_bucket_name t0 = time.clock() dst_bucket.copy_key(k.key, src_bucket_name, k.key) print time.clock() - t0, ' seconds' if len(keys) < maximum_keys: print 'Done backing up.' break result_marker = keys[maximum_keys - 1].key if __name__ =='__main__':main() 

我在Rake任务中使用这个(Rails应用程序):

 desc "Back up a file onto S3" task :backup do S3ID = "*****" S3KEY = "*****" SRCBUCKET = "primary-mzgd" NUM_BACKUP_BUCKETS = 2 Dir.chdir("#{Rails.root}/lib/tasks") system "./do_backup.py #{S3ID} #{S3KEY} #{SRCBUCKET} #{NUM_BACKUP_BUCKETS}" end 

mdahlman的代码不适用于我,但是此命令将bucket1中的所有文件复制到存储区2中的新文件夹(命令也会创build此新文件夹)。

 cp --recursive --include=file_prefix* s3://bucket1/ s3://bucket2/new_folder_name/ 

s3cmd不会只带前缀或通配符,但是你可以使用's3cmd ls sourceBucket'来编写脚本,awk提取对象名称。 然后使用's3cmd cp sourceBucket / name destBucket'复制列表中的每个对象名称。

我在Windows的DOS框中使用这些batch file:

s3list.bat

 s3cmd ls %1 | gawk "/s3/{ print \"\\"\"\"substr($0,index($0,\"s3://\"))\"\\"\"\"; }" 

s3copy.bat

 @for /F "delims=" %%s in ('s3list %1') do @s3cmd cp %%s %2 

您也可以使用使用multithreading的s3funnel:

https://github.com/neelakanta/s3funnel

示例(不显示访问密钥或密钥参数):

s3funnel source-bucket-name list | s3funnel dest-bucket-name copy -source-bucket source-bucket-name –threads = 10