Szybki sposób na wyświetlenie wszystkich plików w zasobniku Amazon S3?

151

Mam wiadro amazon s3, które zawiera dziesiątki tysięcy nazw plików. Jaki jest najłatwiejszy sposób na uzyskanie pliku tekstowego zawierającego wszystkie nazwy plików w zasobniku?

Steve
źródło
Jak wspomina komentarz jlduponta dotyczący odpowiedzi udzielonej przez vdaubry, boto.s3.bucketlistresultset.BucketListResultSetdotyczy warunku „dziesiątki tysięcy nazw plików”, o którym mowa w pytaniu.
chb
1
Należy pamiętać, że w przypadku zasobników z bardzo dużą liczbą obiektów, powiedzmy milionami lub miliardami, poniższe podejścia do kodowania / tworzenia skryptów nie będą działać dobrze. Zamiast tego należy włączyć S3 Inventory i pobrać raport zapasów.
jarmod

Odpowiedzi:

120

Polecam używanie boto . Następnie jest kilka krótkich linii Pythona :

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

Zapisz to jako list.py, otwórz terminal, a następnie uruchom:

$ python list.py > results.txt
Zachary Ozer
źródło
3
Jeśli otrzymasz: boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden Upewnij się, że zasady użytkownika dotyczące klucza dostępu / klucza tajnego mają dostęp do S3.
topherjaynes
1
Otrzymałem błąd 403 i musiałem postępować zgodnie z instrukcją, aby to zadziałało: stackoverflow.com/a/22462419/1143558
Ljubisa Livac
jak przelecieć przez to w bash?
SuperUberDuper
4
Czy możesz dodać do tego wariant za pomocą nowego pakietu boto3?
yeliabsalohcin
@yeliabsalohcin zobacz moją odpowiedź
Casey
62

AWS CLI

Dokumentacja do aws s3 ls

AWS niedawno wydało swoje narzędzia wiersza poleceń. Działa to podobnie jak boto i można je zainstalować za pomocą sudo easy_install awsclilubsudo pip install awscli

Po zainstalowaniu możesz po prostu uruchomić

aws s3 ls

Który pokaże wszystkie dostępne wiadra

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

Następnie możesz wysłać zapytanie do konkretnego zasobnika o pliki.

Polecenie :

aws s3 ls s3://mybucket

Wyjście :

Bucket: mybucket
Prefix:

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

Spowoduje to wyświetlenie wszystkich plików.

Layke
źródło
14
Dodaj --recursiveflagę, aby zobaczyć wszystkie obiekty w określonym katalogu
Chris Bloom,
2
Czy istnieje sposób na przeanalizowanie nazw? Chcę zrobić listę plików w wiadrze s3 do wyliczenia.
Casey
ponadto s3 koduje nazwy plików, które mają być użyte jako adresy URL, są to tylko surowe nazwy plików ..
Casey
42

s3cmd jest nieoceniony do tego typu rzeczy

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

mat kelcey
źródło
1
s3cmdzwraca nazwy plików posortowane według daty. Czy jest jakiś sposób, żebym mógł zwrócić tylko te pliki, które zostały dodane później 2015-10-23 20:46?
SexyBeast
Zwróć uwagę, że jeśli w nazwach plików są spacje, jest to mała usterka, ale nie mam awk-foo, aby to naprawić
Colin D
36

Uważaj, lista amazon zwraca tylko 1000 plików. Jeśli chcesz iterować po wszystkich plikach, musisz podzielić wyniki za pomocą znaczników:

W Ruby za pomocą 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

koniec

Mam nadzieję, że to pomoże, Vincent

vdaubry
źródło
7
boto obsługuje stronicowanie, patrz github.com/boto/boto/blob/develop/boto/s3/bucket.py
jldupont
Dzięki za to, ciężko mi było znaleźć sposób ustawienia znacznika: 1:
Adrian Magdas
20

Aktualizacja 15-02-2019:

To polecenie wyświetli listę wszystkich zasobników w AWS S3:

aws s3 ls

To polecenie wyświetli listę wszystkich obiektów najwyższego poziomu w zasobniku AWS S3:

aws s3 ls bucket-name

To polecenie wyświetli listę WSZYSTKICH obiektów w zasobniku AWS S3:

aws s3 ls bucket-name --recursive

To polecenie umieści listę WSZYSTKICH w zasobniku AWS S3 ... wewnątrz pliku tekstowego w bieżącym katalogu:

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

Khalil Gharbaoui
źródło
To działa, ale nie jest tym, czego potrzebuję. Po prostu wymienia wszystkie przedrostki „najwyższego poziomu”. Czy istnieje sposób na pobranie wszystkich obiektów do zasobnika, prefiksów i wszystkiego?
rinogo
Aktualizacja: odpowiedź od @sysuser jest tym, czego potrzebowałem.
rinogo
@rinogo Może nie pasuje do twoich potrzeb ... ale działa i to się tutaj liczy. Odpowiada potrzebom innych osób jako poprawna odpowiedź.
Khalil Gharbaoui
Jak powiedziałem, działa - dziękuję! Ale to nie odpowiada na pytanie OP. OP poprosił o sposób na „[wyświetlenie] wszystkich nazw plików w zasobniku”. Zawiera tylko obiekty najwyższego poziomu, a nie wszystkie obiekty.
rinogo
2
Aha, ale nie jest to trudne. Po prostu dodaj „--recursive” do polecenia. Dodam to do mojej odpowiedzi dzięki za wskazanie tego
Khalil Gharbaoui,
12

Dla programistów Scala jest to rekurencyjna funkcja wykonywania pełnego skanowania i mapowania zawartości zasobnika AmazonS3 przy użyciu oficjalnego zestawu AWS SDK dla języka 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))
}

Aby wywołać powyższą map()funkcję curried , po prostu przekaż już skonstruowany (i poprawnie zainicjowany) obiekt AmazonS3Client (patrz oficjalny AWS SDK for Java API Reference ), nazwę zasobnika i nazwę prefiksu na pierwszej liście parametrów. Przekaż także funkcję, f()którą chcesz zastosować, aby odwzorować podsumowanie każdego obiektu na drugiej liście parametrów.

Na przykład

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

zwróci pełną listę (key, owner)krotek w tym zasobniku / przedrostku

lub

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

tak, jak zwykle podejście Monady w programowaniu funkcjonalnym

Paolo Angioletti
źródło
W tym kodzie jest błąd. Jeśli początkowy skan zostanie obcięty, ostateczny powrót powróci tylko mapped.toListbez żadnego z poprzednichacc
Mark Wang
Dzięki - zauważ, że AmazonS3Client powinien teraz być po prostu AmazonS3.
Anthony Holland
11

Można to zrobić na kilka sposobów. Korzystanie z Pythona

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)

Innym sposobem jest użycie do tego celu AWS cli

aws s3 ls s3://{bucketname}
example : aws s3 ls s3://testbucket133
Mahesh Mogal
źródło
jeśli aws jest już skonfigurowane, można zamienić linie 2 i 3 nas3 = boto3.resource('s3')
sinapan
Jeśli masz umieszczone zmienne środowiskowe, nie musisz używać zmiennych w sessionmetodzie. AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
Flavio
7

Po zach też poleciłbym boto , ale musiałem trochę zmienić jego kod:

conn = boto.connect_s3('access-key', 'secret'key')
bucket = conn.lookup('bucket-name')
for key in bucket:
    print key.name
Datageek
źródło
3
Modyfikacja była konieczna, ponieważ oryginalny kod nie działał w danym momencie.
Datageek
1
conn.lookupzwraca Nonezamiast wyrzucać S3ResponseError(NoSuchBucket)błąd
Ehtesh Choudhury,
5

Dla boto3 Pythona po użyciu aws configure:

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

bucket = s3.Bucket('name')
for obj in bucket.objects.all():
    print(obj.key)
André
źródło
5

Najpierw upewnij się, jesteś na instance terminali trzeba all accessod S3w IAMktórej używasz. Na przykład użyłem instancji ec2.

pip3 install awscli

Następnie skonfiguruj aws

aws configure

Następnie wypełnijśredniki, np .: -

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

Teraz zobacz wszystkie zasobniki

aws s3 ls

Przechowuj nazwy wszystkich zasobników

aws s3 ls > output.txt

Zobacz całą strukturę plików w wiadrze

aws s3 ls bucket-name --recursive

Przechowuj strukturę plików w każdym zasobniku

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

Mam nadzieję że to pomoże.

Harry_pb
źródło
działa ... ale zabiera całe wiadro
gvasquez
4

Interfejs wiersza polecenia AWS umożliwia szybkie przeglądanie wszystkich plików zasobnika S3 i pomaga w wykonywaniu innych operacji.

Aby użyć AWS CLI, wykonaj poniższe czynności:

  1. Zainstaluj AWS CLI.
  2. Skonfiguruj interfejs wiersza polecenia AWS do korzystania z domyślnych poświadczeń bezpieczeństwa i domyślnego regionu AWS.
  3. Aby zobaczyć wszystkie pliki zasobnika S3, użyj polecenia

    aws s3 ls s3: // nazwa_Twojego_bierka --recursive

Odniesienie do używania AWS cli dla różnych usług AWS: https://docs.aws.amazon.com/cli/latest/reference/

singh30
źródło
3

W Javie możesz uzyskać klucze za pomocą ListObjects (zobacz dokumentację 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.
źródło
Dostępny jest jeszcze jeden prosty interfejs API, który pobiera nazwę zasobnika i wyświetla listę obiektów w nim obecnych. ObjectListing objects = s3client.listObjects (bucketName) link javadoc jest podany poniżej, docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/ ...
Rajesh
2

Koduj w Pythonie przy użyciu niesamowitej biblioteki „boto” . Kod zwraca listę plików w zasobniku, a także obsługuje wyjątki dla brakujących zasobników.

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

Nie zapomnij zastąpić <PLACE_HOLDERS> swoimi wartościami.

Oran
źródło
2

Poniższe polecenie pobierze wszystkie nazwy plików z twojego zasobnika AWS S3 i zapisze do pliku tekstowego w twoim bieżącym katalogu:

aws s3 ls s3://Bucketdirectory/Subdirectory/ | cat >> FileNames.txt
Praveenkumar Sekar
źródło
1

Alternatywnie możesz użyć klienta Minio aka mc. Jego Open Source i kompatybilny z AWS S3. Jest dostępny dla systemów Linux, Windows, Mac, FreeBSD.

Wszystko, co musisz zrobić, to uruchomić polecenie mc ls, aby wyświetlić zawartość.

$ 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

Uwaga:

  • s3: Alias ​​dla Amazon S3
  • kline: nazwa zasobnika AWS S3

Instalowanie klienta Minio dla systemu Linux Pobierz mc dla:

$ chmod 755 mc
$ ./mc --help

Konfigurowanie poświadczeń AWS za pomocą klienta Minio

Host konfiguracji $ mc dodaj mys3 https://s3.amazonaws.com BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

Uwaga: zamień mys3 na alias, który chcesz dla tego konta, a BKIKJAA5BMMU2RHO6IBB, V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 na swój klucz AWS ACCESS-KEY i SECRET-KEY

Mam nadzieję, że to pomoże.

Zastrzeżenie: pracuję dla Minio

koolhead17
źródło
Unikaj udostępniania tajnego klucza IAM w dowolnym miejscu.
Alexey Vazhnov
1

Możesz użyć standardowego interfejsu API S3 -

aws s3 ls s3://root/folder1/folder2/
Nrj
źródło
1

Możesz wyświetlić listę wszystkich plików w zasobniku aws s3 za pomocą polecenia

aws s3 ls path/to/file

i aby zapisać go w pliku, użyj

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

jeśli chcesz dołączyć swój wynik do pliku, w przeciwnym razie:

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

jeśli chcesz wyjaśnić, co zostało napisane wcześniej.

Będzie działać zarówno w systemie Windows, jak i Linux.

Aklank Jain
źródło
1

W javascript możesz użyć

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

aby umieścić wszystkie obiekty w wiadrze. musisz przekazać nazwę zasobnika wewnątrz params (Bucket: name) .

murtaza sanjeliwala
źródło
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
źródło
1
Której klasy S3 używasz? Gdzie mogę to dostać?
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}'
Yordan Georgiev
źródło
3
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu, i uczyniłoby go bardziej użytecznym dla przyszłych czytelników z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
Toby Speight
0

Uproszczona i zaktualizowana wersja odpowiedzi Scala autorstwa 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))
}

Usunięcie elementów ogólnych i użycie ListObjectRequest wygenerowanego przez konstruktory zestawu SDK.

Wildgooze
źródło
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
źródło
2
Myślę, że to prototyp Javy czy coś w tym rodzaju, ale proszę wyjaśnij to.
Doncho Gunchev
0

W PHP możesz uzyskać pełną listę obiektów AWS-S3 wewnątrz określonego zasobnika, używając następującego wywołania

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

Możesz przekierować wyjście powyższego kodu do pliku, aby uzyskać listę kluczy.

Shriganesh Shintre
źródło
0

Użyj plumbum, aby zawinąć CLI, a otrzymasz jasną składnię:

import plumbum as pb
folders = pb.local['aws']('s3', 'ls')
JaviOverflow
źródło
0

spróbuj tego skryptu bash. używa polecenia curl bez konieczności stosowania jakichkolwiek zewnętrznych zależności

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
źródło
-2

NAJŁATWIEJSZY sposób na uzyskanie bardzo użytecznego pliku tekstowego polega na pobraniu przeglądarki S3 Browser http://s3browser.com/ i skorzystaniu z generatora adresów internetowych w celu utworzenia listy pełnych ścieżek linków. Jest bardzo poręczny i wymaga około 3 kliknięć.

-Browse to Folder
-Select All
-Generate Urls

Powodzenia.

Elliot Thornton
źródło