Как отфильтровать и перечислить все объекты в папке s3 по определенному размеру с помощью python

#python #amazon-web-services #amazon-s3 #amazon-sagemaker

#python #amazon-web-services #amazon-s3 #amazon-sagemaker

Вопрос:

Я пытаюсь получить все файлы указанного размера в папке корзины s3. Как мне выполнить итерацию по корзине и отфильтровать файлы по указанному размеру? Я также хочу вернуть имена файлов с правильным размером.

 s3 = boto3.client('s3')
s3.list_objects_v2(Bucket = 'my-images')
  

Пример вывода

  u'Key': u'detail/01018535.jpg',
   u'LastModified': datetime.datetime(2019, 1, 23, 0, 48, 41, tzinfo=tzlocal()),
   u'Size': 13535,
   u'StorageClass': 'STANDARD'},
  {u'ETag': '"cd65991a1c6f118e8b036208a30028a7"',
   u'Key': u'detail/0119AF2.jpg',
   u'LastModified': datetime.datetime(2019, 1, 10, 17, 17, tzinfo=tzlocal()),
   u'Size': 12984,
   u'StorageClass': 'STANDARD'}
  

например, предположим, что я хотел бы выполнить поиск по размеру 12984.
Затем он вернет «Ключ»

Ответ №1:

Если вы хотите использовать boto3, я использую эту функцию для поиска объектов с нулевым байтом. Вы можете настроить его в соответствии с вашими потребностями, отфильтровав по определенному размеру

 import boto3

def get_empty_objects(bucket_name, prefixes):
    """
    get list of objects from a given s3 prefix recursively
    """
    results = []
    for prefix in prefixes:
        s3client = boto3.client('s3')
        paginator = s3client.get_paginator("list_objects_v2")
        paginator_result = paginator.paginate(
            Bucket=bucket_name, Prefix=prefix)
        try:
            for object in paginator_result.search('Contents'):
                if object['Size'] == 0:
                    results.append("s3://"   bucket_name   "/"   object['Key'])
        except Exception as err:
            print(">>> Error processing objects of [s3://"   bucket_name  
                  "/"   prefix   "] - "   str(err))
        print(">>> Returning "   str(len(results))   " objects for [s3://"   bucket_name   "/"   prefix   "]")
    return results
  

Использование:

 get_empty_objects("mybucket", ["prefix1/", "prefix2/"])
  

Ответ №2:

Вы можете использовать --query выражение:

 aws s3api list-objects-v2 --bucket my-images --query 'Contents[?Size==`12984`].[Key]' --output text
  

Я заключил [Key] в квадратные скобки, чтобы заставить каждый объект отображаться в отдельной строке.

Этот синтаксис работает в командной строке Mac. Windows могут потребоваться другие кавычки.

Советы по использованию таких выражений см. В: Руководство по JMESpath

Комментарии:

1. Я знаю, что OP искал точный размер, но также полезно находить файлы, размер которых превышает определенный размер, например: --query "Contents[?Size>=`1048576`] | sort_by(@, amp;Size)"

2. При использовании BASH обратные метки нужно экранировать обратными косыми чертами. В PowerShell в Windows мне не удалось заставить экранирование работать правильно (например, удвоение обратных ссылок не помогло)