Maneira rápida de listar todos os arquivos no bucket do Amazon S3?

151

Eu tenho um Amazon S3 bucket que possui dezenas de milhares de nomes de arquivos. Qual é a maneira mais fácil de obter um arquivo de texto que lista todos os nomes de arquivos no bucket?

Steve
fonte
Como mencionado no comentário de jldupont sobre a resposta fornecida pelo vdaubry, boto.s3.bucketlistresultset.BucketListResultSettrata da condição "dezenas de milhares de nomes de arquivos" mencionada na pergunta.
chb 29/05
1
Esteja ciente de que, para depósitos com um número muito grande de objetos, digamos milhões ou bilhões, as abordagens de codificação / script abaixo não funcionarão bem. Você deve ativar o S3 Inventory e recuperar um relatório de inventário.
jarmod 31/01

Respostas:

120

Eu recomendo usar o boto . Então são algumas linhas 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')

Salve isso como list.py, abra um terminal e execute:

$ python list.py > results.txt
Zachary Ozer
fonte
3
Se você obtiver: boto.exception.S3ResponseError: S3ResponseError: 403 Proibido Verifique se a política do usuário da chave de Acesso / Segredo tem acesso ao S3.
Topherjaynes
1
Eu tenho 403 de erro, e eu tinha que seguir estas instruções, a fim de torná-lo para o trabalho: stackoverflow.com/a/22462419/1143558
Ljubisa Livac
como você faz um loop através dele no bash?
SuperUberDuper
4
Você poderia adicionar uma variante a isso usando o novo pacote boto3?
precisa saber é o seguinte
@yeliabsalohcin see my answer
Casey
62

CLI da AWS

Documentação para aws s3 ls

A AWS lançou recentemente suas ferramentas de linha de comando. Isso funciona como o boto e pode ser instalado usando sudo easy_install awscliousudo pip install awscli

Depois de instalar, você pode simplesmente executar

aws s3 ls

O que mostrará todos os seus baldes disponíveis

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

Em seguida, você pode consultar um intervalo específico para arquivos.

Comando :

aws s3 ls s3://mybucket

Saída :

Bucket: mybucket
Prefix:

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

Isso mostrará todos os seus arquivos.

Layke
fonte
14
Adicionar a --recursivebandeira para ver todos os objetos sob o diretório especificado
Chris Bloom
2
Existe uma maneira de analisar os nomes? Eu estou olhando para fazer uma lista de arquivos em um balde s3 para enumerar.
Casey #
Além disso, s3 codifica os nomes de arquivos para ser utilizado como URLs, estes são nomes de arquivos apenas matérias ..
Casey
42

s3cmd é inestimável para esse tipo de coisa

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

mat kelcey
fonte
1
s3cmdretorna os nomes de arquivos classificados por data. Existe alguma maneira de fazê-lo retornar, digamos apenas os arquivos que foram adicionados depois 2015-10-23 20:46?
SexyBeast #
Note-se que se os nomes de arquivos têm espaços isto tem uma pequena falha, mas eu não tenho o awk-foo para corrigi-lo
Colin D
36

Cuidado, a lista da Amazon retorna apenas 1000 arquivos. Se você deseja iterar sobre todos os arquivos, pagine os resultados usando marcadores:

Em ruby ​​usando o 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

fim

Espero que isso ajude, vincent

vdaubry
fonte
7
boto alças de paginação, consulte github.com/boto/boto/blob/develop/boto/s3/bucket.py
jldupont
Obrigado por isso, tive dificuldade em encontrar como definir o marcador: 1:
Adrian Magdas
20

Atualização 15-02-2019:

Este comando fornecerá uma lista de todos os buckets no AWS S3:

aws s3 ls

Este comando fornecerá uma lista de todos os objetos de nível superior dentro de um bucket do AWS S3:

aws s3 ls bucket-name

Este comando fornecerá uma lista de TODOS os objetos dentro de um bucket do AWS S3:

aws s3 ls bucket-name --recursive

Este comando colocará uma lista de ALL dentro de um bucket do AWS S3 ... dentro de um arquivo de texto em seu diretório atual:

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

Khalil Gharbaoui
fonte
Isso funciona, mas não é realmente o que eu preciso. Apenas lista todos os prefixos "de nível superior". Existe uma maneira de obter todos os objetos em um balde, prefixos e tudo?
Rinogo 14/02/19
Atualização: A resposta de @sysuser é o que eu precisava.
Rinogo 14/02/19
@rinogo Talvez não atenda às suas necessidades ... mas funciona e é isso que conta aqui. Cabe às necessidades de outras pessoas como resposta correta.
Khalil Gharbaoui
Como eu disse, funciona - obrigado! Mas isso não responde à pergunta do OP. O OP pediu uma maneira de "[listar] todos os nomes de arquivos no balde". Isso lista apenas objetos de nível superior, nem todos os objetos.
Rinogo 14/02/19
2
Ah, mas isso não é difícil de fazer. Basta adicionar '--recursive' ao comando. Vou adicioná-lo para a minha resposta obrigado por apontar isso
Khalil Gharbaoul
12

Para desenvolvedores do Scala, aqui é uma função recursiva executar uma verificação completa e mapear o conteúdo de um bucket do AmazonS3 usando o AWS SDK oficial 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 a map()função ao curry acima , basta passar o objeto AmazonS3Client já construído (e inicializado corretamente) (consulte a referência oficial da API do AWS SDK para Java ), o nome do bucket e o nome do prefixo na primeira lista de parâmetros. Passe também a função que f()você deseja aplicar para mapear cada resumo de objeto na segunda lista de parâmetros.

Por exemplo

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

retornará a lista completa de (key, owner)tuplas nesse intervalo / prefixo

ou

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

como você normalmente abordaria por mônadas na programação funcional

Paolo Angioletti
fonte
Há um erro neste código. Se a verificação inicial é truncado, o retorno final só retornará mapped.toListsem qualquer do anterioracc
Mark Wang
Obrigado - observe que o AmazonS3Client agora deve ser apenas o AmazonS3.
Anthony Holland
11

Existem algumas maneiras de fazer isso. 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)

Outra maneira é usar o AWS cli para isso

aws s3 ls s3://{bucketname}
example : aws s3 ls s3://testbucket133
Mahesh Mogal
fonte
AWS se já está configurado, pode-se substituir as linhas 2 e 3, coms3 = boto3.resource('s3')
sinapan
Se você tiver as variáveis ​​de ambiente colocadas, não precisará usar as variáveis ​​no sessionmétodo AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
Flavio
7

Depois do zach, eu também recomendaria o boto , mas eu precisava fazer uma pequena diferença no código dele:

conn = boto.connect_s3('access-key', 'secret'key')
bucket = conn.lookup('bucket-name')
for key in bucket:
    print key.name
Datageek
fonte
3
A modificação foi necessária porque o código original não funcionou por vez.
Datageek
1
conn.lookupretorna Noneao invés de lançar um S3ResponseError(NoSuchBucket)erro
Ehtesh Choudhury
5

Para o boto3 do Python depois de ter usado aws configure:

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

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

Primeiro verifique se você está em um instance terminale você tem all accessde S3em IAMque você está usando. Por exemplo, usei uma instância ec2.

pip3 install awscli

Em seguida, configure o aws

aws configure

Em seguida, preencha os critérios externos ex: -

$ 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)

Agora, veja todos os baldes

aws s3 ls

Armazenar o nome de todos os buckets

aws s3 ls > output.txt

Veja toda a estrutura de arquivos em um bucket

aws s3 ls bucket-name --recursive

Armazene a estrutura de arquivos em cada bloco

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

Espero que isto ajude.

Harry_pb
fonte
funciona ... mas leva para e-ver para obter o balde inteiro
gvasquez 21/03
4

A AWS CLI pode permitir que você veja todos os arquivos de um bucket S3 rapidamente e também ajuda na execução de outras operações.

Para usar a CLI da AWS, siga as etapas abaixo:

  1. Instale a CLI da AWS.
  2. Configure a CLI da AWS para usar credenciais de segurança padrão e região padrão da AWS.
  3. Para ver todos os arquivos de um bucket S3, use o comando

    aws s3 ls s3: // your_bucket_name --recursive

Referência para usar o AWS cli para diferentes serviços da AWS: https://docs.aws.amazon.com/cli/latest/reference/

cantarh30
fonte
3

Em Java, você pode obter as chaves usando o ListObjects (consulte a documentação da 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());
H6
fonte
Há mais uma API simples disponível, que pega o nome do bucket e lista os objetos presentes nele. ObjectListing objects = s3client.listObjects (bucketName) O link javadoc é fornecido abaixo, docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/…
Rajesh
2

Codifique em python usando a incrível biblioteca "boto" . O código retorna uma lista de arquivos em um bucket e também lida com exceções para os buckets ausentes.

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() ]

Não se esqueça de substituir <PLACE_HOLDERS> pelos seus valores.

Oran
fonte
2

O comando abaixo obterá todos os nomes de arquivo do seu bucket do AWS S3 e gravará no arquivo de texto no diretório atual:

aws s3 ls s3://Bucketdirectory/Subdirectory/ | cat >> FileNames.txt
Praveenkumar Sekar
fonte
1

Como alternativa, você pode usar o Minio Client, também conhecido como mc. É de código aberto e compatível com o AWS S3. Está disponível para Linux, Windows, Mac, FreeBSD.

Tudo que você precisa fazer é executar o comando mc ls para listar o conteúdo.

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

Nota:

  • s3: alias para o Amazon S3
  • kline: nome do bucket do AWS S3

Instalando o Minio Client Linux Download mc para:

$ chmod 755 mc
$ ./mc --help

Configurando credenciais da AWS com o Minio Client

host de configuração do $ mc add mys3 https://s3.amazonaws.com BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

Nota: Substitua mys3 pelo alias desejado para esta conta e, BKIKJAA5BMMU2RHO6IBB, V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 pelo AWS ACCESS-KEY e SECRET-KEY

Espero que ajude.

Isenção de responsabilidade: eu trabalho para o Minio

koolhead17
fonte
Evite compartilhar a chave secreta do IAM em qualquer lugar.
Alexey Vazhnov
1

Você pode usar a API padrão s3 -

aws s3 ls s3://root/folder1/folder2/
Nrj
fonte
1

Você pode listar todos os arquivos no bucket do aws s3 usando o comando

aws s3 ls path/to/file

e para salvá-lo em um arquivo, use

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

se você deseja anexar seu resultado em um arquivo, caso contrário:

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

se você quiser limpar o que foi escrito antes.

Funcionará tanto no Windows quanto no Linux.

Aklank Jain
fonte
1

Em javascript você pode usar

s3.listObjects (parâmetros, função (erro, resultado) {});

para colocar todos os objetos dentro do balde. você precisa passar o nome do bucket dentro dos parâmetros (Bucket: name) .

murtaza sanjeliwala
fonte
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;
}
Sandeep Penmetsa
fonte
1
Qual classe S3 você está usando? Onde eu consigo isso?
IDev247 02/10/2012
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}'
Yordan Georgiev
fonte
3
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
precisa
0

Versão simplificada e atualizada da resposta 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))
}

Removendo os genéricos e usando o ListObjectRequest gerado pelos construtores do SDK.

wildgooze
fonte
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));

}
user1172192
fonte
2
Eu acho que este é um protótipo Java ou algo assim, mas por favor explique.
Doncho Gunchev 19/06/12
0

No PHP, você pode obter uma lista completa dos objetos do AWS-S3 dentro do bucket específico usando a seguinte chamada

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

Você pode redirecionar a saída do código acima para um arquivo para obter a lista de chaves.

Shriganesh Shintre
fonte
0

Use plumbum para quebrar o cli e você terá uma sintaxe clara:

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

por favor, tente este script bash. ele usa o comando curl sem precisar de dependências 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}"
Bahram Zaeri
fonte
-2

A maneira MAIS FÁCIL de obter um arquivo de texto muito utilizável é baixar o S3 Browser http://s3browser.com/ e usar o Gerador de URLs da Web para produzir uma lista de caminhos completos do link. É muito útil e envolve cerca de 3 cliques.

-Browse to Folder
-Select All
-Generate Urls

Boa sorte para você.

Elliot Thornton
fonte