【问题标题】:Moving file based on filename with Amazon S3使用 Amazon S3 根据文件名移动文件
【发布时间】:2021-08-23 13:27:30
【问题描述】:

需要根据其名称将 Amazon S3 文件移动到名称相同的相应文件夹。这是针对 AWS 上的 python 中的自动化脚本。文件名加 1。

例如,一个叫my_file_section_a,然后下一个叫my_file_section_b1,然后下一个叫my_file_section_b2,以此类推。这些文件夹将被称为my_file_section_a、my_file_section_b1 等等。

代码如下:

from __future__import print_function
import boto3
import time, urllib
import json

print("*"*80)
print("Initializing...")
print("*"*80)

s3 = boto3.client('s3')

def lambda_handler(event, context):

    source_bucket = event['Records'[0]['s3']['bucket']['name']
    object_key = event['Records'][0]['s3']['object']['key']
    target_bucket = 'myfilelambdadestination'
    copy_source = {'Bucket': source_bucket, 'Key': object_key}
    print("Source bucket: ", source_bucket)
    print("Target bucket: ", target_bucket)
    print("Log Stream name: ",context.log_stream_name)
    print("Log Group name: ",context.log_group_name)
    print("Request ID: ",context.aws_request_id)
    print("Mem. limits(MB) ", context.memory_limit_in_mb)
    try:
        print("Using waiter to waiting for object to persist through s3 service")
        waiter = s3.get_waiter('object_exists')
        waiter.wait(Bucket=source_bucket, Key = object_key)
        s3.copy_object(Bucket=target_bucket, Key = object_key, CopySource = copy_source)
        return response['ContentType']
    except Exception as err:
        print("Error -" +str(err))
        return e

如何将基于名称的文件移动到名称相同的文件夹中?

【问题讨论】:

  • 仅供参考,您不需要使用服务员。 AWS Lambda 函数只会在对象创建后触发。
  • 您的要求有点不清楚。你是说对象foo应该被复制到foo/foo1,但是如果那个对象已经存在,那么它应该被复制到foo/foo2?
  • 每个文件都是独一无二的,因为它只有一种类型。例如,文件名为 my_file_section_a,然后是 my_file_section_a1。存在与文件具有相同名称的文件夹。它将仅根据其名称进行复制,而不会复制到其他文件夹中,例如 my_file_section_b。
  • 请通过提供更多示例来阐明您的要求。你是说foo 应该转到foo/foo,而bar 应该转到bar/bar? (以及为什么?)
  • 是的,文件名 foo 应该放在名为 foo 的文件夹中。一个名为 bar 的文件应该进入一个名为 bar 的文件夹。此外,这些文件按字母顺序递增,因此 foo_2 应放入名为 foo_2 的文件夹中。然后会有一个名为 goo 的文件,它应该进入一个名为 goo 的文件夹,然后是另一个名为 goo_2 的文件,它应该进入一个文件名 goo_2 等等。目标是将文件移动到同名的同一个文件夹中。原因是出于组织目的,文件不必手动移动到这些文件夹中。

标签: python amazon-web-services amazon-s3 aws-lambda boto3


【解决方案1】:

新文件夹是不带扩展名的文件名。根据 object_key 的外观,您可能会调整此代码

object_key = 'my_file_section_b2.txt'
new_object_prefix = object_key.rsplit('/', 1)[-1].split('.')[0]
new_object_key = new_object_prefix + '/' + object_key
new_object_key
'my_file_section_b2/my_file_section_b2.txt'

【讨论】:

    【解决方案2】:

    这是一个 AWS Lambda 函数,它将一个对象复制到同名目录,然后删除原始对象。

    只会从bucket的root复制对象,避免复制的对象再次触发Lambda函数,造成死循环。 (Amazon S3 很大,但不是无限的!)如果您的目标是不同的存储桶,则没有必要这样做。

    import boto3
    import urllib
    
    def lambda_handler(event, context):
        
        # Get the bucket and object key from the Event
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
        
        # Only copy objects that were uploaded to the bucket root (to avoid an infinite loop)
        if '/' not in key:
            
            # Copy object
            s3_client = boto3.client('s3')
            s3_client.copy_object(
                Bucket = bucket,
                Key = f"{key}/{key}",
                CopySource= {'Bucket': bucket, 'Key': key}
            )
            
            # Delete source object
            s3_client.delete_object(
                Bucket = bucket,
                Key = key
            )
    

    该函数需要一个具有GetObject 和PutObject(可能更多?)权限的 IAM 角色。创建此 AWS Lambda 函数后,在 Amazon S3 存储桶上创建一个 Event 以在创建对象时触发该函数。

    【讨论】:

    • 感谢您的澄清。我已经使用我上传的文件运行了脚本,但在 AWS 中没有发生任何事情。
    • AWS Lambda 函数缩进为在创建对象时由 Amazon S3 事件触发。它不是意味着直接“运行”。因此,配置存储桶以在上传对象时触发该功能。对象的 Bucket 和 Key 会自动传递给 Lambda 函数,该函数会复制和删除对象。
    猜你喜欢
    • 2015-10-09
    • 1970-01-01
    • 2013-11-20
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    相关资源
    最近更新 更多