Un moyen rapide de répertorier tous les fichiers dans le compartiment Amazon S3?


151

J'ai un seau amazon s3 qui contient des dizaines de milliers de noms de fichiers. Quel est le moyen le plus simple d'obtenir un fichier texte qui répertorie tous les noms de fichiers du compartiment?


Comme l'indique le commentaire de jldupont sur la réponse fournie par vdaubry, boto.s3.bucketlistresultset.BucketListResultSetaborde la condition des «dizaines de milliers de noms de fichiers» mentionnée dans la question.
chb

1
Sachez que pour les buckets avec un très grand nombre d'objets, disons des millions ou des milliards, les approches de codage / script ci-dessous ne fonctionneront pas bien. Vous devez à la place activer l'inventaire S3 et récupérer un rapport d'inventaire.
jarmod le

Réponses:


120

Je recommanderais d'utiliser boto . Ensuite, c'est quelques lignes rapides 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')

Enregistrez-le sous list.py, ouvrez un terminal, puis exécutez:

$ python list.py > results.txt

3
Si vous obtenez: boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden Assurez-vous que la stratégie utilisateur pour la clé d'accès / secret a accès au S3.
topherjaynes

1
J'ai eu une erreur 403 et j'ai dû suivre ces instructions pour que cela fonctionne: stackoverflow.com/a/22462419/1143558
Ljubisa Livac

comment le parcourez-vous en bash?
SuperUberDuper

4
Pourriez-vous ajouter une variante à cela en utilisant le nouveau package boto3?
yeliabsalohcin

@yeliabsalohcin voir ma réponse
Casey

62

AWS CLI

Documentation pour AWS S3 LS

AWS a récemment publié ses outils de ligne de commande. Cela fonctionne un peu comme boto et peut être installé en utilisant sudo easy_install awscliousudo pip install awscli

Une fois que vous avez installé, vous pouvez alors simplement exécuter

aws s3 ls

Qui vous montrera tous vos seaux disponibles

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

Vous pouvez ensuite interroger un compartiment spécifique pour les fichiers.

Commande :

aws s3 ls s3://mybucket

Sortie :

Bucket: mybucket
Prefix:

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

Cela vous montrera tous vos fichiers.


14
Ajouter le --recursivedrapeau pour voir tous les objets dans le répertoire spécifié
Chris Bloom

2
Existe-t-il un moyen d'analyser les noms? Je cherche à faire une liste de fichiers dans un seau s3 à énumérer.
Casey

de plus, s3 encode les noms de fichiers à utiliser comme URL, ce ne sont que des noms de fichiers bruts ..
Casey

42

s3cmd est inestimable pour ce genre de chose

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


1
s3cmdrenvoie les noms de fichiers triés par date. Y a-t-il un moyen de le faire revenir en disant uniquement les fichiers qui ont été ajoutés après 2015-10-23 20:46?
SexyBeast

Notez que si les noms de fichiers ont des espaces, cela a un petit problème mais je n'ai pas le awk-foo pour le réparer
Colin D

36

Attention, la liste Amazon ne renvoie que 1000 fichiers. Si vous souhaitez parcourir tous les fichiers, vous devez paginer les résultats à l'aide de marqueurs:

En rubis avec 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

fin

J'espère que cela aide, Vincent



Merci pour cela, j'ai eu du mal à trouver comment régler le marqueur: 1:
Adrian Magdas

20

Mise à jour 15-02-2019:

Cette commande vous donnera une liste de tous les compartiments dans AWS S3:

aws s3 ls

Cette commande vous donnera une liste de tous les objets de niveau supérieur dans un compartiment AWS S3:

aws s3 ls bucket-name

Cette commande vous donnera une liste de TOUS les objets dans un compartiment AWS S3:

aws s3 ls bucket-name --recursive

Cette commande placera une liste de TOUS dans un compartiment AWS S3 ... dans un fichier texte dans votre répertoire actuel:

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


Cela fonctionne mais ce n'est pas vraiment ce dont j'ai besoin. Il répertorie simplement tous les préfixes "de premier niveau". Existe-t-il un moyen d'obtenir tous les objets dans un seau, les préfixes et tout?
rinogo le

Mise à jour: La réponse de @sysuser est ce dont j'avais besoin.
rinogo

@rinogo Cela ne correspond peut-être pas à vos besoins ... mais cela fonctionne et c'est ce qui compte ici. Cela correspond aux besoins des autres personnes en tant que réponse correcte.
Khalil Gharbaoui

Comme je l'ai dit, cela fonctionne - merci! Mais cela ne répond pas à la question d'OP. OP a demandé un moyen de "[lister] tous les noms de fichiers dans le compartiment". Cela répertorie uniquement les objets de niveau supérieur, pas tous les objets.
rinogo le

2
Ah mais ce n'est pas difficile à faire. Ajoutez simplement «--recursive» à la commande. Je vais l'ajouter à ma réponse, merci de l'avoir signalé
Khalil Gharbaoui

12

Pour les développeurs Scala, il s'agit ici d'une fonction récursive permettant d'exécuter une analyse complète et de mapper le contenu d'un bucket AmazonS3 à l'aide du SDK AWS officiel pour 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))
}

Pour appeler la map()fonction curry ci-dessus , transmettez simplement l'objet AmazonS3Client déjà construit (et correctement initialisé) (reportez-vous au AWS SDK for Java API Reference ), le nom du compartiment et le nom du préfixe dans la première liste de paramètres. Passez également la fonctionf() vous souhaitez appliquer pour mapper chaque résumé d'objet dans la deuxième liste de paramètres.

Par exemple

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

renverra la liste complète des (key, owner)tuples dans ce compartiment / préfixe

ou

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

comme vous le feriez normalement avec les Monades dans la programmation fonctionnelle


Il y a un bug avec ce code. Si l'analyse initiale est tronquée, le retour final ne reviendra que mapped.toListsans aucun des précédentsacc
Mark Wang

Merci - notez qu'AmazonS3Client ne devrait plus être qu'AmazonS3.
Anthony Holland

11

Il y a plusieurs façons de procéder. Utiliser 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)

Une autre façon consiste à utiliser AWS cli pour cela

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

si aws est déjà configuré, on peut remplacer les lignes 2 et 3 pars3 = boto3.resource('s3')
sinapan

Si vous avez placé les variables d'environnement, vous n'avez pas besoin d'utiliser les variables de la sessionméthode. AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
Flavio

7

Après zach, je recommanderais également boto , mais je devais faire une légère différence dans son code:

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

3
La modification était nécessaire car le code d'origine ne fonctionnait pas à la fois.
Datageek

1
conn.lookuprenvoie Noneau lieu de lancer une S3ResponseError(NoSuchBucket)erreur
Ehtesh Choudhury


5

Pour le boto3 de Python après avoir utilisé aws configure:

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

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

5

D' abord , assurez - vous que vous êtes sur un instance terminalet vous avez all accessde S3en IAMvous utilisez. Par exemple, j'ai utilisé une instance ec2.

pip3 install awscli

Ensuite, configurez aws

aws configure

Ensuite, remplissez les références 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)

Maintenant, voir tous les seaux

aws s3 ls

Stocker le nom de tous les buckets

aws s3 ls > output.txt

Voir toute la structure de fichiers dans un bucket

aws s3 ls bucket-name --recursive

Stocker la structure des fichiers dans chaque compartiment

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

J'espère que cela t'aides.


fonctionne ... mais prend for-e-ver pour obtenir le seau entier
gvasquez

4

AWS CLI peut vous permettre de voir rapidement tous les fichiers d'un compartiment S3 et vous aider à effectuer d'autres opérations également.

Pour utiliser l'AWS CLI, suivez les étapes ci-dessous:

  1. Installez l' AWS CLI.
  2. Configurer AWS CLI pour utiliser les informations d'identification de sécurité par défaut et la région AWS par défaut.
  3. Pour voir tous les fichiers d'un compartiment S3, utilisez la commande

    aws s3 ls s3: // votre_nom_bucket --recursive

Référence pour utiliser AWS cli pour différents services AWS: https://docs.aws.amazon.com/cli/latest/reference/


3

En Java, vous pouvez obtenir les clés à l'aide de ListObjects (voir la documentation 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());

Il existe une autre API simple disponible, qui prend le nom du compartiment et répertorie les objets qui y sont présents. ObjectListing objects = s3client.listObjects (bucketName) Le lien javadoc est donné ci-dessous, docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/…
Rajesh

2

Code en python en utilisant l'impressionnante lib "boto" . Le code renvoie une liste de fichiers dans un compartiment et gère également les exceptions pour les compartiments manquants.

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'oubliez pas de remplacer <PLACE_HOLDERS> par vos valeurs.


2

La commande ci-dessous obtiendra tous les noms de fichiers de votre compartiment AWS S3 et les écrit dans un fichier texte de votre répertoire actuel:

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

1

Vous pouvez également utiliser Minio Client aka mc. Son Open Source et compatible avec AWS S3. Il est disponible pour Linux, Windows, Mac, FreeBSD.

Tout ce que vous avez à faire est d'exécuter la commande mc ls pour lister le contenu.

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

Remarque:

  • s3: Alias ​​pour Amazon S3
  • kline: nom du compartiment AWS S3

Installation de Minio Client Linux Téléchargez mc pour:

$ chmod 755 mc
$ ./mc - aide

Configuration des informations d'identification AWS avec Minio Client

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

Remarque: veuillez remplacer mys3 par l'alias que vous souhaitez pour ce compte et, BKIKJAA5BMMU2RHO6IBB, V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 avec votre AWS ACCESS-KEY et SECRET-KEY

J'espère que ça aide.

Clause de non-responsabilité: je travaille pour Minio


Veuillez éviter de partager la clé secrète IAM n'importe où.
Alexey Vazhnov

1

Vous pouvez utiliser l'API s3 standard -

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

1

Vous pouvez lister tous les fichiers, dans le bucket aws s3 en utilisant la commande

aws s3 ls path/to/file

et pour l'enregistrer dans un fichier, utilisez

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

si vous souhaitez ajouter votre résultat dans un fichier sinon:

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

si vous voulez effacer ce qui a été écrit auparavant.

Cela fonctionnera à la fois sous Windows et Linux.


1

En javascript, vous pouvez utiliser

s3.listObjects (paramètres, fonction (err, résultat) {});

pour obtenir tous les objets à l'intérieur du seau. vous devez passer le nom du compartiment dans les paramètres (Bucket: nom) .


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
Quelle classe S3 utilisez-vous? Où peux-je le recevoir?
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
Merci pour cet extrait de code, qui pourrait fournir une aide limitée et immédiate. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez formulées.
Toby Speight

0

Version simplifiée et mise à jour de la réponse 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))
}

Suppression des génériques et utilisation du ListObjectRequest généré par les générateurs du 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
Je suppose que c'est un prototype Java ou quelque chose du genre, mais veuillez l'expliquer.
Doncho Gunchev

0

En PHP, vous pouvez obtenir la liste complète des objets AWS-S3 dans un compartiment spécifique à l'aide de l'appel suivant

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

Vous pouvez rediriger la sortie du code ci-dessus dans un fichier pour obtenir la liste des clés.


0

Utilisez plumbum pour envelopper le cli et vous aurez une syntaxe claire:

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

0

veuillez essayer ce script bash. il utilise la commande curl sans avoir besoin de dépendances externes

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

Le moyen le plus simple d'obtenir un fichier texte très utilisable est de télécharger le navigateur S3 http://s3browser.com/ et d'utiliser le générateur d'URL Web pour produire une liste de chemins de liens complets. Il est très pratique et implique environ 3 clics.

-Browse to Folder
-Select All
-Generate Urls

Bonne chance à vous.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.