Modo rapido per elencare tutti i file nel bucket Amazon S3?


151

Ho un bucket Amazon S3 che contiene decine di migliaia di nomi di file. Qual è il modo più semplice per ottenere un file di testo che elenca tutti i nomi dei file nel bucket?


Come accennato dal commento di jldupont sulla risposta fornita da vdaubry, boto.s3.bucketlistresultset.BucketListResultSetaffronta la condizione "decine di migliaia di nomi di file" menzionata nella domanda.
chb

1
Tenere presente che per i bucket con un numero molto elevato di oggetti, ad esempio milioni o miliardi, gli approcci di codifica / scripting di seguito non funzioneranno bene. Dovresti invece abilitare S3 Inventory e recuperare un rapporto di inventario.
jarmod

Risposte:


120

Consiglierei di usare boto . Quindi sono un paio di righe di 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')

Salvalo come list.py, apri un terminale ed esegui:

$ python list.py > results.txt

3
Se ottieni: boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden Assicurati che il criterio utente per la chiave di accesso / segreto abbia accesso a S3.
topherjaynes,

1
Ho ricevuto l'errore 403 e ho dovuto seguire queste istruzioni per farlo funzionare: stackoverflow.com/a/22462419/1143558
Ljubisa Livac

come lo fai scorrere in bash?
SuperUberDuper

4
Potresti aggiungere una variante a questo usando il nuovo pacchetto boto3?
yeliabsalohcin

@yeliabsalohcin vedi la mia risposta
Casey il

62

CLI AWS

Documentazione per aws s3 ls

AWS ha recentemente rilasciato i suoi strumenti da riga di comando. Funziona in modo molto simile a boto e può essere installato usando sudo easy_install awscliosudo pip install awscli

Una volta installato, puoi semplicemente eseguire

aws s3 ls

Che ti mostrerà tutti i tuoi secchi disponibili

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

È quindi possibile eseguire una query su un bucket specifico per i file.

Comando :

aws s3 ls s3://mybucket

Uscita :

Bucket: mybucket
Prefix:

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

Questo ti mostrerà tutti i tuoi file.


14
Aggiungi il --recursiveflag per vedere tutti gli oggetti nella directory specificata
Chris Bloom,

2
C'è un modo per analizzare i nomi? Sto cercando di fare un elenco di file in un bucket S3 per enumerare.
Casey,

inoltre, s3 codifica i nomi dei file da utilizzare come URL, questi sono solo nomi di file non elaborati.
Casey,

42

s3cmd è prezioso per questo tipo di cose

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


1
s3cmdrestituisce i nomi dei file ordinati per data. C'è un modo in cui posso farlo tornare dire solo quei file che sono stati aggiunti dopo 2015-10-23 20:46?
SexyBeast,

Nota che se i nomi dei file hanno spazi questo ha un piccolo problema tecnico ma non ho l'imbarazzo di sistemarlo
Colin D

36

Attenzione, l'elenco amazon restituisce solo 1000 file. Se vuoi iterare su tutti i file devi impaginare i risultati usando i marcatori:

In ruby ​​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

fine

Spero che questo aiuti, Vincent



Grazie per questo, ho avuto difficoltà a trovare il modo di impostare il marker: 1:
Adrian Magdas,

20

Aggiornamento 15-02-2019:

Questo comando ti fornirà un elenco di tutti i bucket in AWS S3:

aws s3 ls

Questo comando ti fornirà un elenco di tutti gli oggetti di livello superiore all'interno di un bucket AWS S3:

aws s3 ls bucket-name

Questo comando ti darà un elenco di TUTTI gli oggetti all'interno di un bucket AWS S3:

aws s3 ls bucket-name --recursive

Questo comando inserirà un elenco di TUTTI all'interno di un bucket AWS S3 ... all'interno di un file di testo nella directory corrente:

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


Funziona ma non è proprio quello di cui ho bisogno. Elenca solo tutti i prefissi di "livello superiore". C'è un modo per ottenere tutti gli oggetti in un bucket, prefissi e tutti?
Rinogo,

Aggiornamento: la risposta di @sysuser è ciò di cui avevo bisogno.
Rinogo,

@rinogo Forse non si adatta alle tue esigenze ... ma funziona e questo è ciò che conta qui. Si adatta alle esigenze di altri ppl come risposta corretta.
Khalil Gharbaoui,

Come ho detto, funziona - grazie! Ma non risponde alla domanda di OP. OP ha chiesto un modo per "[elencare] tutti i nomi dei file nel bucket". Questo elenca solo gli oggetti di livello superiore, non tutti gli oggetti.
Rinogo,

2
Ah, ma non è difficile da fare. Aggiungi '--recursive' al comando. Lo aggiungerò alla mia risposta, grazie per
averlo

12

Per gli sviluppatori Scala, qui è una funzione ricorsiva eseguire una scansione completa e mappare i contenuti di un bucket AmazonS3 utilizzando l' SDK AWS ufficiale per 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))
}

Per invocare la map()funzione curry sopra descritta , è sufficiente passare l'oggetto AmazonS3Client già costruito (e correttamente inizializzato) (fare riferimento all'SDK AWS ufficiale per riferimento API Java ), il nome del bucket e il nome del prefisso nel primo elenco di parametri. Passa anche la funzionef() si desidera applicare per mappare ciascun riepilogo degli oggetti nel secondo elenco di parametri.

Per esempio

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

restituirà l'elenco completo delle (key, owner)tuple in quel bucket / prefisso

o

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

come normalmente ti avvicineresti alle Monadi nella Programmazione Funzionale


C'è un bug con questo codice. Se la scansione iniziale viene troncata, il ritorno finale ritornerà solo mapped.toListsenza uno dei precedentiacc
Mark Wang

Grazie - nota che AmazonS3Client ora dovrebbe essere solo AmazonS3.
Anthony Holland,

11

Ci sono un paio di modi in cui puoi farlo. 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)

Un altro modo è utilizzare AWS cli per questo

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

se aws è già configurato, è possibile sostituire le righe 2 e 3 cons3 = boto3.resource('s3')
sinapan

Se sono state posizionate le variabili di ambiente, non è necessario utilizzare le variabili nel sessionmetodo. AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
Flavio,

7

Dopo zach consiglierei anche boto , ma dovevo fare una leggera differenza nel suo codice:

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

3
La modifica era necessaria perché il codice originale non funzionava alla volta.
Datageek,

1
conn.lookupritorna Noneinvece di lanciare un S3ResponseError(NoSuchBucket)errore
Ehtesh Choudhury,


5

Per il boto3 di Python dopo aver usato aws configure:

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

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

5

In primo luogo assicurarsi che si sta su un instance terminale hai all accessdi S3in IAMche si sta utilizzando. Ad esempio ho usato un'istanza ec2.

pip3 install awscli

Quindi configura aws

aws configure

Quindi compilare gli outcredantials 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)

Ora, vedi tutti i secchi

aws s3 ls

Memorizza il nome di tutti i secchi

aws s3 ls > output.txt

Vedi tutta la struttura dei file in un bucket

aws s3 ls bucket-name --recursive

Memorizza la struttura dei file in ciascun bucket

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

Spero che questo ti aiuti.


funziona ... ma richiede for-e-ver per ottenere l'intero bucket
gvasquez

4

L'interfaccia della riga di comando di AWS ti consente di visualizzare rapidamente tutti i file di un bucket S3 e di eseguire altre operazioni.

Per utilizzare l'interfaccia della riga di comando di AWS, procedi come segue:

  1. Installa l' interfaccia della riga di comando di AWS.
  2. Configurazione interfaccia della riga di comando di AWS per l'utilizzo delle credenziali di sicurezza predefinite e della regione AWS predefinita.
  3. Per vedere tutti i file di un bucket S3 utilizzare il comando

    aws s3 ls s3: // your_bucket_name --recursive

Riferimento per l'uso di AWS cli per diversi servizi AWS: https://docs.aws.amazon.com/cli/latest/reference/


3

In Java è possibile ottenere le chiavi utilizzando ListObjects (consultare la documentazione 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());

È disponibile un'altra API semplice, che prende il nome del bucket ed elenca gli oggetti presenti al suo interno. ObjectListing objects = s3client.listObjects (bucketName) il link javadoc è riportato di seguito, docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/…
Rajesh,

2

Codice in Python usando il fantastico "boto" lib . Il codice restituisce un elenco di file in un bucket e gestisce anche le eccezioni per i bucket mancanti.

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

Non dimenticare di sostituire <PLACE_HOLDERS> con i tuoi valori.


2

Il comando seguente otterrà tutti i nomi dei file dal bucket AWS S3 e scriverà nel file di testo nella directory corrente:

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

1

In alternativa puoi usare Minio Client aka mc. È open source e compatibile con AWS S3. È disponibile per Linux, Windows, Mac, FreeBSD.

Tutto quello che devi fare è eseguire il comando mc ls per elencare i contenuti.

$ 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] 50 KiB pi.png
[2016-05-10 14:34:39 IST] 365KiB upton.pdf

Nota:

  • s3: Alias ​​per Amazon S3
  • kline: nome bucket AWS S3

Installazione di Minio Client Linux Scarica mc per:

$ chmod 755 mc
$ ./mc --help

Impostazione delle credenziali AWS con Minio Client

$ mc config host aggiungi mys3 https://s3.amazonaws.com BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

Nota: Sostituisci mys3 con l'alias che desideri per questo account e, BKIKJAA5BMMU2RHO6IBB, V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 con AWS ACCESS-KEY e SECRET-KEY

Spero che sia d'aiuto.

Disclaimer: lavoro per Minio


Si prega di evitare di condividere la chiave segreta IAM ovunque.
Alexey Vazhnov,

1

È possibile utilizzare API standard s3 -

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

1

Puoi elencare tutti i file, nel bucket aws s3 usando il comando

aws s3 ls path/to/file

e per salvarlo in un file, utilizzare

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

se si desidera aggiungere il risultato in un file altrimenti:

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

se vuoi cancellare ciò che è stato scritto prima.

Funzionerà sia in Windows che in Linux.


1

In javascript puoi usare

s3.listObjects (parametri, funzione (err, risultato) {});

per ottenere tutti gli oggetti all'interno del secchio. devi passare il nome del bucket all'interno dei parametri (Bucket: name) .


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
Quale classe S3 stai usando? Dove lo posso prendere?
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
Grazie per questo frammento di codice, che potrebbe fornire un aiuto limitato e immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Si prega di modificare la risposta di aggiungere qualche spiegazione, tra le ipotesi che hai fatto.
Toby Speight,

0

Versione semplificata e aggiornata della risposta alla Scala di 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))
}

Eliminare i generici e utilizzare ListObjectRequest generato dai costruttori 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
Immagino che questo sia un prototipo di Java o qualcosa del genere, ma per favore spiegalo.
Doncho Gunchev,

0

In PHP puoi ottenere un elenco completo di oggetti AWS-S3 all'interno di un bucket specifico usando la seguente chiamata

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

Puoi reindirizzare l'output del codice sopra in un file per ottenere un elenco di chiavi.


0

Usa il piombo per avvolgere il cli e avrai una sintassi chiara:

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

0

per favore prova questo script bash. utilizza il comando curl senza la necessità di dipendenze esterne

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

Il modo più semplice per ottenere un file di testo molto utilizzabile è scaricare il browser S3 http://s3browser.com/ e utilizzare il generatore di URL Web per produrre un elenco di percorsi di collegamento completi. È molto utile e comporta circa 3 clic.

-Browse to Folder
-Select All
-Generate Urls

Buona fortuna a te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.