¿Forma rápida de listar todos los archivos en el bucket de Amazon S3?


151

Tengo un cubo amazon s3 que tiene decenas de miles de nombres de archivo. ¿Cuál es la forma más fácil de obtener un archivo de texto que enumere todos los nombres de archivo en el depósito?


Como aludió el comentario de jldupont sobre la respuesta proporcionada por vdaubry, boto.s3.bucketlistresultset.BucketListResultSetaborda la condición de "decenas de miles de nombres de archivos" mencionada en la pregunta.
chb

1
Tenga en cuenta que para los cubos con una gran cantidad de objetos, digamos millones o miles de millones, los enfoques de codificación / scripting a continuación no funcionarán bien. En su lugar, debe habilitar el inventario S3 y recuperar un informe de inventario.
jarmod

Respuestas:


120

Recomiendo usar boto . Entonces es un par de líneas rápidas de python :

from boto.s3.connection import S3Connection

conn = S3Connection('access-key','secret-access-key')
bucket = conn.get_bucket('bucket')
for key in bucket.list():
    print key.name.encode('utf-8')

Guarde esto como list.py, abra una terminal y luego ejecute:

$ python list.py > results.txt

3
Si obtiene: boto.exception.S3ResponseError: S3ResponseError: 403 Prohibido Asegúrese de que la política de usuario para la clave de Acceso / Secreto tenga acceso al S3.
topherjaynes

1
Recibí un error 403 y tuve que seguir estas instrucciones para que funcione: stackoverflow.com/a/22462419/1143558
Ljubisa Livac

¿Cómo lo recorres en bash?
SuperUberDuper el

44
¿Podría agregar una variante a esto usando el nuevo paquete boto3?
yeliabsalohcin

@yeliabsalohcin mira mi respuesta
Casey

62

AWS CLI

Documentación para aws s3 ls

AWS ha lanzado recientemente sus herramientas de línea de comandos. Esto funciona de manera muy similar a boto y se puede instalar usando sudo easy_install awscliosudo pip install awscli

Una vez que haya instalado, simplemente puede ejecutar

aws s3 ls

Que le mostrará todos sus cubos disponibles

CreationTime Bucket
       ------------ ------
2013-07-11 17:08:50 mybucket
2013-07-24 14:55:44 mybucket2

Luego puede consultar un depósito específico para archivos.

Comando :

aws s3 ls s3://mybucket

Salida :

Bucket: mybucket
Prefix:

      LastWriteTime     Length Name
      -------------     ------ ----
                           PRE somePrefix/
2013-07-25 17:06:27         88 test.txt

Esto le mostrará todos sus archivos.


14
Agregue la --recursivebandera para ver todos los objetos en el directorio especificado
Chris Bloom

2
¿Hay alguna forma de analizar los nombres? Estoy buscando hacer una lista de archivos en un cubo s3 para enumerar.
Casey

Además, s3 codifica los nombres de archivo que se utilizarán como URL, estos son solo nombres de archivo sin procesar ..
Casey

42

s3cmd es invaluable para este tipo de cosas

$ s3cmd ls -r s3://yourbucket/ | awk '{print $4}' > objects_in_bucket


1
s3cmddevuelve los nombres de archivo ordenados por fecha. ¿Hay alguna forma en que pueda hacer que vuelva, digamos solo aquellos archivos que se han agregado después 2015-10-23 20:46?
SexyBeast

Tenga en cuenta que si los nombres de archivo tienen espacios, esto tiene una pequeña falla, pero no tengo el awk-foo para solucionarlo
Colin D

36

Tenga cuidado, amazon list solo devuelve 1000 archivos. Si desea iterar sobre todos los archivos, debe paginar los resultados con marcadores:

En rubí usando aws-s3

bucket_name = 'yourBucket'
marker = ""

AWS::S3::Base.establish_connection!(
  :access_key_id => 'your_access_key_id',
  :secret_access_key => 'your_secret_access_key'
)

loop do
  objects = Bucket.objects(bucket_name, :marker=>marker, :max_keys=>1000)
  break if objects.size == 0
  marker = objects.last.key

  objects.each do |obj|
      puts "#{obj.key}"
  end
end

final

Espero que esto ayude, Vincent


77
boto maneja la paginación, consulte github.com/boto/boto/blob/develop/boto/s3/bucket.py
jldupont el

Gracias por esto, me costó encontrar la forma de establecer el marcador: 1:
Adrian Magdas

20

Actualización 15-02-2019:

Este comando le dará una lista de todos los depósitos en AWS S3:

aws s3 ls

Este comando le dará una lista de todos los objetos de nivel superior dentro de un depósito de AWS S3:

aws s3 ls bucket-name

Este comando le dará una lista de TODOS los objetos dentro de un depósito de AWS S3:

aws s3 ls bucket-name --recursive

Este comando colocará una lista de TODOS dentro de un depósito de AWS S3 ... dentro de un archivo de texto en su directorio actual:

aws s3 ls bucket-name --recursive | cat >> file-name.txt


Esto funciona pero no es realmente lo que necesito. Simplemente enumera todos los prefijos de "nivel superior". ¿Hay alguna manera de obtener todos los objetos en un cubo, prefijos y todo?
rinogo

Actualización: La respuesta de @sysuser es lo que necesitaba.
rinogo

@rinogo Quizás no se ajuste a tus necesidades ... pero funciona y eso es lo que cuenta aquí. Se ajusta a la necesidad de otras personas como respuesta correcta.
Khalil Gharbaoui

Como dije, funciona, ¡gracias! Pero no responde la pregunta de OP. OP solicitó una forma de "[enumerar] todos los nombres de archivo en el depósito". Esto solo enumera los objetos de nivel superior, no todos los objetos.
rinogo

2
Ajá pero eso no es difícil de hacer. Simplemente agregue '--recursive' al comando. Lo
agregaré

12

Para los desarrolladores de Scala, aquí es una función recursiva ejecutar un escaneo completo y asignar el contenido de un bucket de AmazonS3 usando el SDK oficial de AWS para Java

import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.{S3ObjectSummary, ObjectListing, GetObjectRequest}
import scala.collection.JavaConversions.{collectionAsScalaIterable => asScala}

def map[T](s3: AmazonS3Client, bucket: String, prefix: String)(f: (S3ObjectSummary) => T) = {

  def scan(acc:List[T], listing:ObjectListing): List[T] = {
    val summaries = asScala[S3ObjectSummary](listing.getObjectSummaries())
    val mapped = (for (summary <- summaries) yield f(summary)).toList

    if (!listing.isTruncated) mapped.toList
    else scan(acc ::: mapped, s3.listNextBatchOfObjects(listing))
  }

  scan(List(), s3.listObjects(bucket, prefix))
}

Para invocar la map()función currículum anterior , simplemente pase el objeto AmazonS3Client ya construido (e inicializado correctamente) (consulte el AWS SDK oficial para Java API Reference ), el nombre del depósito y el nombre del prefijo en la primera lista de parámetros. También pase la función f()que desea aplicar para asignar cada resumen de objeto en la segunda lista de parámetros.

Por ejemplo

val keyOwnerTuples = map(s3, bucket, prefix)(s => (s.getKey, s.getOwner))

devolverá la lista completa de (key, owner)tuplas en ese cubo / prefijo

o

map(s3, "bucket", "prefix")(s => println(s))

como normalmente te acercarías mónadas en la programación funcional


Hay un error con este código. Si el escaneo inicial se trunca, el retorno final solo volverá mapped.toListsin ninguno de los anterioresacc
Mark Wang

Gracias, tenga en cuenta que AmazonS3Client ahora debería ser solo AmazonS3.
Anthony Holland

11

Hay dos formas de hacerlo. Usando Python

import boto3

sesssion = boto3.Session(aws_access_key_id, aws_secret_access_key)

s3 = sesssion.resource('s3')

bucketName = 'testbucket133'
bucket = s3.Bucket(bucketName)

for obj in bucket.objects.all():
    print(obj.key)

Otra forma es usar AWS cli para ello

aws s3 ls s3://{bucketname}
example : aws s3 ls s3://testbucket133

si aws ya está configurado, uno puede reemplazar las líneas 2 y 3 cons3 = boto3.resource('s3')
sinapan

Si tiene colocadas las variables de entorno, no necesita usar las variables en el sessionmétodo. AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
Flavio

7

Después de zach también recomendaría boto , pero necesitaba hacer una ligera diferencia en su código:

conn = boto.connect_s3('access-key', 'secret'key')
bucket = conn.lookup('bucket-name')
for key in bucket:
    print key.name

3
La modificación fue necesaria porque el código original no funcionaba a la vez.
Datageek

1
conn.lookupregresa en Nonelugar de arrojar un S3ResponseError(NoSuchBucket)error
Ehtesh Choudhury


5

Para el boto3 de Python después de haber usado aws configure:

import boto3
s3 = boto3.resource('s3')

bucket = s3.Bucket('name')
for obj in bucket.objects.all():
    print(obj.key)

5

En primer lugar asegurarse de que están en una instance terminaly tiene all accessde S3en IAMque está utilizando. Por ejemplo, usé una instancia ec2.

pip3 install awscli

Luego configure aws

aws configure

Luego complete los credenciales ej: -

$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json (or just press enter)

Ahora, mira todos los cubos

aws s3 ls

Almacenar todos los nombres de cubos

aws s3 ls > output.txt

Ver toda la estructura de archivos en un cubo

aws s3 ls bucket-name --recursive

Almacene la estructura de archivos en cada cubo

aws s3 ls bucket-name --recursive > file_Structure.txt

Espero que esto ayude.


funciona ... pero toma para siempre obtener el cubo completo
gvasquez

4

AWS CLI puede permitirle ver todos los archivos de un bucket de S3 rápidamente y ayudarlo a realizar otras operaciones también.

Para usar AWS CLI, siga los pasos a continuación:

  1. Instalar en pc AWS CLI.
  2. Configurar AWS CLI para usar las credenciales de seguridad predeterminadas y la Región de AWS predeterminada.
  3. Para ver todos los archivos de un depósito S3, use el comando

    aws s3 ls s3: // your_bucket_name --recursive

Referencia para usar AWS cli para diferentes servicios de AWS: https://docs.aws.amazon.com/cli/latest/reference/


3

En Java, puede obtener las claves utilizando ListObjects (consulte la documentación de AWS )

FileWriter fileWriter;
BufferedWriter bufferedWriter;
// [...]

AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());        

ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
.withBucketName(bucketName)
.withPrefix("myprefix");
ObjectListing objectListing;

do {
    objectListing = s3client.listObjects(listObjectsRequest);
    for (S3ObjectSummary objectSummary : 
        objectListing.getObjectSummaries()) {
        // write to file with e.g. a bufferedWriter
        bufferedWriter.write(objectSummary.getKey());
    }
    listObjectsRequest.setMarker(objectListing.getNextMarker());
} while (objectListing.isTruncated());

Hay una API más simple disponible, que toma el nombre del depósito y enumera los objetos presentes en él. ObjectListing objects = s3client.listObjects (bucketName) El enlace javadoc se proporciona a continuación, docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/…
Rajesh

2

Codifique en Python usando la impresionante lib "boto" . El código devuelve una lista de archivos en un depósito y también maneja excepciones para depósitos perdidos.

import boto

conn = boto.connect_s3( <ACCESS_KEY>, <SECRET_KEY> )
try:
    bucket = conn.get_bucket( <BUCKET_NAME>, validate = True )
except boto.exception.S3ResponseError, e:
    do_something() # The bucket does not exist, choose how to deal with it or raise the exception

return [ key.name.encode( "utf-8" ) for key in bucket.list() ]

No olvide reemplazar los <PLACE_HOLDERS> con sus valores.


2

El siguiente comando obtendrá todos los nombres de archivo de su bucket de AWS S3 y escribirá en el archivo de texto en su directorio actual:

aws s3 ls s3://Bucketdirectory/Subdirectory/ | cat >> FileNames.txt

1

Alternativamente, puede usar Minio Client, también conocido como mc. Es de código abierto y compatible con AWS S3. Está disponible para Linux, Windows, Mac, FreeBSD.

Todo lo que tienes que hacer es ejecutar mc ls para enumerar los contenidos.

$ mc ls s3 / kline /
[30/04/2016 13:20:47 IST] 1.1MiB 1.jpg
[30/04/2016 16:03:55 IST] 7.5KiB docker.png
[30/04/2016 15:16:17 IST] 50KiB pi.png
[10/05/2016 14:34:39 IST] 365KiB upton.pdf

Nota:

  • s3: Alias ​​para Amazon S3
  • kline: nombre del depósito de AWS S3

Instalación de Minio Client Linux Descargue mc para:

$ chmod 755 mc
$ ./mc --ayuda

Configuración de credenciales de AWS con Minio Client

$ mc host de configuración agregar mys3 https://s3.amazonaws.com BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

Nota: Reemplace mys3 con el alias que desee para esta cuenta y, BKIKJAA5BMMU2RHO6IBB, V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 con su AWS ACCESS-KEY y SECRET-KEY

Espero eso ayude.

Descargo de responsabilidad: trabajo para Minio


Evite compartir la clave secreta de IAM en cualquier lugar.
Alexey Vazhnov

1

Puede usar la API estándar s3:

aws s3 ls s3://root/folder1/folder2/

1

Puede enumerar todos los archivos, en el bucket aws s3 usando el comando

aws s3 ls path/to/file

y para guardarlo en un archivo, use

aws s3 ls path/to/file >> save_result.txt

si desea agregar su resultado en un archivo, de lo contrario:

aws s3 ls path/to/file > save_result.txt

si quieres borrar lo que se escribió antes.

Funcionará tanto en Windows como en Linux.


1

En javascript puedes usar

s3.listObjects (params, function (err, result) {});

para obtener todos los objetos dentro del cubo. debe pasar el nombre del depósito dentro de los parámetros (Depósito: nombre) .


1
function showUploads(){
    if (!class_exists('S3')) require_once 'S3.php';
    // AWS access info
    if (!defined('awsAccessKey')) define('awsAccessKey', '234567665464tg');
    if (!defined('awsSecretKey')) define('awsSecretKey', 'dfshgfhfghdgfhrt463457');
    $bucketName = 'my_bucket1234';
    $s3 = new S3(awsAccessKey, awsSecretKey);
    $contents = $s3->getBucket($bucketName);
    echo "<hr/>List of Files in bucket : {$bucketName} <hr/>";
    $n = 1;
    foreach ($contents as $p => $v):
        echo $p."<br/>";
        $n++;
    endforeach;
}

1
¿Qué clase de S3 estás usando? ¿Dónde puedo conseguirlo?
iDev247

0
# find like file listing for s3 files
aws s3api --profile <<profile-name>> \
--endpoint-url=<<end-point-url>> list-objects \
--bucket <<bucket-name>> --query 'Contents[].{Key: Key}'

3
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
Toby Speight

0

Versión simplificada y actualizada de la respuesta Scala de Paolo:

import scala.collection.JavaConversions.{collectionAsScalaIterable => asScala}
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.model.{ListObjectsRequest, ObjectListing, S3ObjectSummary}

def buildListing(s3: AmazonS3, request: ListObjectsRequest): List[S3ObjectSummary] = {
  def buildList(listIn: List[S3ObjectSummary], bucketList:ObjectListing): List[S3ObjectSummary] = {
    val latestList: List[S3ObjectSummary] = bucketList.getObjectSummaries.toList

    if (!bucketList.isTruncated) listIn ::: latestList
    else buildList(listIn ::: latestList, s3.listNextBatchOfObjects(bucketList))
  }

  buildList(List(), s3.listObjects(request))
}

Eliminando los genéricos y usando ListObjectRequest generado por los constructores SDK.


0
public static Dictionary<string, DateTime> ListBucketsByCreationDate(string AccessKey, string SecretKey)  
{  

    return AWSClientFactory.CreateAmazonS3Client(AccessKey,
        SecretKey).ListBuckets().Buckets.ToDictionary(s3Bucket => s3Bucket.BucketName,
        s3Bucket => DateTime.Parse(s3Bucket.CreationDate));

}

2
Supongo que este es un prototipo de Java o algo así, pero explícalo.
Doncho Gunchev

0

En PHP, puede obtener una lista completa de objetos AWS-S3 dentro de un depósito específico utilizando la siguiente llamada

$S3 = \Aws\S3\S3Client::factory(array('region' => $region,));
$iterator = $S3->getIterator('ListObjects', array('Bucket' => $bucket));
foreach ($iterator as $obj) {
    echo $obj['Key'];
}

Puede redirigir la salida del código anterior a un archivo para obtener una lista de claves.


0

Use plumbum para envolver el cli y tendrá una sintaxis clara:

import plumbum as pb
folders = pb.local['aws']('s3', 'ls')

0

por favor prueba este script bash. utiliza el comando curl sin necesidad de dependencias externas

bucket=<bucket_name>
region=<region_name>
awsAccess=<access_key>
awsSecret=<secret_key>
awsRegion="${region}"
baseUrl="s3.${awsRegion}.amazonaws.com"

m_sed() {
  if which gsed > /dev/null 2>&1; then
    gsed "$@"
  else
    sed "$@"
  fi
}

awsStringSign4() {
  kSecret="AWS4$1"
  kDate=$(printf         '%s' "$2" | openssl dgst -sha256 -hex -mac HMAC -macopt "key:${kSecret}"     2>/dev/null | m_sed 's/^.* //')
  kRegion=$(printf       '%s' "$3" | openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kDate}"    2>/dev/null | m_sed 's/^.* //')
  kService=$(printf      '%s' "$4" | openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kRegion}"  2>/dev/null | m_sed 's/^.* //')
  kSigning=$(printf 'aws4_request' | openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kService}" 2>/dev/null | m_sed 's/^.* //')
  signedString=$(printf  '%s' "$5" | openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kSigning}" 2>/dev/null | m_sed 's/^.* //')
  printf '%s' "${signedString}"
}

if [ -z "${region}" ]; then
  region="${awsRegion}"
fi


# Initialize helper variables

authType='AWS4-HMAC-SHA256'
service="s3"
dateValueS=$(date -u +'%Y%m%d')
dateValueL=$(date -u +'%Y%m%dT%H%M%SZ')

# 0. Hash the file to be uploaded

# 1. Create canonical request

# NOTE: order significant in ${signedHeaders} and ${canonicalRequest}

signedHeaders='host;x-amz-content-sha256;x-amz-date'

canonicalRequest="\
GET
/

host:${bucket}.s3.amazonaws.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:${dateValueL}

${signedHeaders}
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

# Hash it

canonicalRequestHash=$(printf '%s' "${canonicalRequest}" | openssl dgst -sha256 -hex 2>/dev/null | m_sed 's/^.* //')

# 2. Create string to sign

stringToSign="\
${authType}
${dateValueL}
${dateValueS}/${region}/${service}/aws4_request
${canonicalRequestHash}"

# 3. Sign the string

signature=$(awsStringSign4 "${awsSecret}" "${dateValueS}" "${region}" "${service}" "${stringToSign}")

# Upload

curl -g -k "https://${baseUrl}/${bucket}" \
  -H "x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" \
  -H "x-amz-Date: ${dateValueL}" \
  -H "Authorization: ${authType} Credential=${awsAccess}/${dateValueS}/${region}/${service}/aws4_request,SignedHeaders=${signedHeaders},Signature=${signature}"

-2

La forma MÁS FÁCIL de obtener un archivo de texto muy útil es descargar S3 Browser http://s3browser.com/ y usar el generador de URLs web para producir una lista de rutas de enlace completas. Es muy útil e implica unos 3 clics.

-Browse to Folder
-Select All
-Generate Urls

La mejor de las suertes para ti.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.