Aws-cli: aws s3 ls - localizar arquivos pela data de modificação?

Criado em 21 jan. 2015  ·  87Comentários  ·  Fonte: aws/aws-cli

Oi,
Gostaríamos de poder pesquisar um intervalo com muitos milhares (provavelmente chegando a centenas de milhares) de objetos e pastas / prefixos para localizar objetos que foram adicionados ou atualizados recentemente. Executar aws s3 ls em todo o balde várias vezes ao dia e, em seguida, classificar a lista parece ineficiente. Existe uma maneira de simplesmente solicitar uma lista de objetos com um tempo modificado <,>, = um determinado carimbo de data / hora?

Além disso, somos cobrados uma vez pela solicitação aws s3 ls ou uma vez por cada um dos objetos retornados pela solicitação?

Novo no github, gostaria de saber o suficiente para contribuir com código real ... agradeço a ajuda.

guidance

Comentários muito úteis

@jwieder Isso não ajuda o usuário a diminuir o número de chamadas da lista para s3. Digamos que todos os dias você armazene cerca de 1000 artigos de notícias em um balde. Então, do lado do cliente, deseja obter artigos dos últimos 3 dias por padrão (e mais apenas se explicitamente solicitado). Ter que buscar uma lista de todos os artigos desde o início dos tempos, digamos 100k, leva tempo e acumula custos de rede (porque uma única chamada de lista retornará apenas até 1000 itens). Seria muito mais agradável poder dizer "Dê-me uma lista de itens criados / modificados desde 3 dias atrás".

Todos 87 comentários

A API S3 não oferece suporte para isso, portanto, a única maneira de fazer isso usando apenas o S3 é fazer a classificação do lado do cliente.

Quanto ao preço S3 , usamos uma solicitação ListObjects que retorna 1000 objetos por vez. Portanto, você será cobrado por uma solicitação LIST a cada 1000 objetos ao usar aws s3 ls .

Outra alternativa é armazenar um índice auxiliar fora de S3, por exemplo, dynamodb. Deixe-me saber se você tem alguma dúvida.

Obrigado

Embora essa funcionalidade pareça estar ausente do aws-cli, é muito fácil fazer um script no bash. Por exemplo:

#!/bin/bash
DATE=$(date +%Y-%m-%d)
aws s3 ls s3://bucket.example.com/somefolder/ | grep ${DATE}

@jwieder Isso não ajuda o usuário a diminuir o número de chamadas da lista para s3. Digamos que todos os dias você armazene cerca de 1000 artigos de notícias em um balde. Então, do lado do cliente, deseja obter artigos dos últimos 3 dias por padrão (e mais apenas se explicitamente solicitado). Ter que buscar uma lista de todos os artigos desde o início dos tempos, digamos 100k, leva tempo e acumula custos de rede (porque uma única chamada de lista retornará apenas até 1000 itens). Seria muito mais agradável poder dizer "Dê-me uma lista de itens criados / modificados desde 3 dias atrás".

Exatamente!

No domingo, 17 de janeiro de 2016 às 23h53, PuchatekwSzortach <
notificaçõ[email protected]> escreveu:

@jwieder https://github.com/jwieder Isso não ajuda a diminuir o usuário
número de chamadas da lista para s3. Diga que todos os dias você armazena cerca de 1000 notícias
artigos em um balde. Então, do lado do cliente, deseja obter artigos dos últimos 3
dias por padrão (e mais apenas se explicitamente solicitado). Ter que buscar um
lista de todos os artigos desde o início dos tempos, digamos 100k, leva tempo
e acumula custos de rede (porque uma única chamada de lista retornará apenas
para 1000 itens). Seria muito mais agradável poder dizer "Dê-me uma lista de
itens criados / modificados desde 3 dias atrás ".

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/aws/aws-cli/issues/1104#issuecomment -172425517.

@PuchatekwSzortach @ChrisSLT Você está certo, desculpe pela minha resposta esfarrapada; e concordo que esse tipo de funcionalidade seria muito útil no aws-cli. A combinação de deixar esse recurso básico de fora e cobrar por listagens de arquivos é altamente suspeita. Até que a AWS pare de penny-penny e introduza a listagem por propriedades de arquivo, aqui está outra ideia que usei que é mais relevante para este tópico do que minha primeira resposta: Para arquivos que precisam ser rastreados dessa forma, os arquivos são nomeados com um carimbo de data / hora . Uma lista de arquivos é armazenada em um arquivo de texto local (ou poderia ser db se você tiver zilhões de arquivos com que se preocupar). A procura de uma data envolve então a abertura do arquivo, a procura de nomes de arquivos que correspondam à data de hoje podem ser mais ou menos assim:

while read -r fileName
Faz
if ["$ fileName" == "$ TODAY"]; então
aws s3 sync $ BUCKETURL / some / local / directory --exclude "*" --include "$ fileName"
fi
concluído <"$ FILE"

Onde $ FILE é o índice do seu nome de arquivo local e $ TODAY é a data que você está procurando. Você precisará alterar a condição neste loop, mas espero que isso possa lhe dar uma ideia.

Fazer as coisas dessa maneira o livra de quaisquer cobranças relacionadas à listagem dos arquivos em seu intervalo; mas também depende do cliente que você está realizando a pesquisa ter acesso à lista de arquivos local ... dependendo da arquitetura do seu aplicativo / sistema que pode tornar esse tipo de abordagem inviável. De qualquer forma, espero que isso ajude e peço desculpas novamente por minha resposta derpy anterior.

Concordo e obrigado

Na terça-feira, 19 de janeiro de 2016 às 10h, Josh Wieder [email protected]
escreveu:

@PuchatekwSzortach https://github.com/PuchatekwSzortach @ChrisSLT
https://github.com/ChrisSLT Você está certo, desculpe pela minha resposta esfarrapada; e
Eu concordo que esse tipo de funcionalidade seria muito útil no aws-cli. o
combinação de deixar esse recurso básico de fora e cobrança por listagens de arquivos
é altamente suspeito. Até que a AWS pare de economizar e introduza a listagem por
propriedades do arquivo, aqui está outra ideia que usei que é mais relevante
a este tópico, então minha primeira resposta: Para arquivos que precisam ser rastreados neste
forma, os arquivos são nomeados com um carimbo de data / hora. Uma lista de arquivos é armazenada em um local
arquivo de texto (ou poderia ser db se você tiver zilhões de arquivos para se preocupar).
A busca por uma data envolve então a abertura do arquivo, a procura de nomes de arquivos
que correspondem à data de hoje podem ser mais ou menos assim:

while read -r fileName
Faz
if ["$ fileName" == "$ TODAY"]; então
aws s3 sync $ BUCKETURL / some / local / directory --exclude "*" --include
"$ fileName"
fi
concluído <"$ FILE"

Onde $ FILE é o seu índice de nome de arquivo local e $ TODAY é a data em que você está
Procurando por. Você precisará alterar a condição neste loop, mas
espero que isso possa lhe dar uma ideia.

Fazer as coisas dessa maneira o livra de quaisquer encargos relacionados à listagem do
arquivos em seu balde; mas também depende do cliente que você está conduzindo
a pesquisa de ter acesso à lista de arquivos local ... dependendo do seu
arquitetura de aplicativo / sistema que pode fazer este tipo de abordagem
inviável. De qualquer forma, espero que isso ajude e peço desculpas novamente por meu anterior
resposta derpy.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/aws/aws-cli/issues/1104#issuecomment -172878454.

Existe uma maneira de fazer isso com o s3api e a função --query. Isso é testado em OSX
aws s3api list-objects --bucket "bucket-name" --query 'Contents [? LastModified> = 2016-05-20 ] []. {Key: Key}'
você pode filtrar usando jq ou grep para fazer o processamento com as outras funções s3api.

Editar: não tenho certeza por que eles não estão aparecendo, mas você tem que usar crases para cercar a data que você está consultando

É possível criar pastas para cada dia e, dessa forma, você acessará apenas os arquivos de hoje ou no máximo as pastas de ontem para obter os arquivos mais recentes.

sim. Embora você possa achar mais fácil simplesmente usar um prefixo de data para suas chaves (você não pode consultar uma combinação de nome de intervalo / nome de pasta usando a opção --bucket). Usar o prefixo de data permitirá que você use o sinalizador --prefix no cli e acelere suas consultas, pois a AWS recomenda o uso de números ou hashes no início dos nomes de chave para aumentar os tempos de resposta.

@willstruebing , sua solução ainda não reduz o número de chamadas S3 API, a complexidade das consultas do lado do servidor ou a quantidade de dados enviados pela rede. O parâmetro --query executa apenas a filtragem jmespath do lado do cliente.

@kislyuk Concordo plenamente que isso não responde às questões de eficiência. No entanto, minha intenção era responder à pergunta específica:

Is there a way to simply request a list of objects with a modified time <, >, = a certain timestamp?

Essa questão básica é como acabei neste tópico e, portanto, achei razoável incluir uma resposta para ela. O problema é rotulado como "aws s3 ls - localizar arquivos pela data de modificação?".

Eu adoraria ouvir as idéias de alguém sobre as partes da questão de eficiência, já que não tenho nenhuma e ainda estou curioso.

#for i em s3cmd ls | awk {'print $3'} ; fazer aws s3 ls $ i --recursive; feito >> s3-full.out

Qual é o padrão para arquivos de retorno da AWS? Ele os retorna em ordem alfabética ou pela modificação mais recente, ou qual é o critério usado quando você solicita seu primeiro lote de 1000 nomes de arquivo?

Concordo que certamente deve haver algum tipo de filtro (classificar por data, por nome, etct) que você pode usar quando solicitar arquivos ... definitivamente um recurso ausente. :(

Eu concordo que essa filtragem deve ser do lado do servidor e é uma necessidade básica.

+1 para consulta / filtragem do lado do servidor

+1 para filtragem do lado do servidor

Ainda muito necessário, +1

De acordo com @chescales e o resto, +1 para filtragem do lado do servidor

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Como isso já não é um recurso?

+100000

+ 1e999

+1

+1

+1

+1

+1

+1

+1

+1

+65535

O comentário de @willstruebing funcionou para mim, por exemplo:

aws s3api list-objects --bucket "mybucket" --prefix "some/prefix" --query "Contents[?LastModified>=`2018-08-22`].{Key: Key}"

oh, deixa pra lá - eu vejo depois de observar o tráfego de rede desse comando que todas as chaves ainda estão sendo baixadas de s3 e aws cli está fazendo a filtragem do lado do cliente!

+1

+1

+1

+1

e os filtros --exclude e --include?

! / bin / bash

DATA = $ (data +% Y-% m-% d)
aws s3 ls s3: //bucket.example.com/algumapasta/ --excluir " " --incluir " $ {DATE} *"

+1

+1

+1 milhão

+1

+ ∞

+ ∞ + 1

+1

+1

+1

++

+1

+1

+1

+1 :( :(

Acho que faz parte do modelo de precificação da AWS, armazenamento super barato mas pago para acessar. Bom para arquivos grandes, mas irá arruiná-lo se você quiser consultar / gerenciar milhões de arquivos pequenos.

+1

Eu acho que é por isso que eles criaram Atena? outra maneira de faturar enquanto adiciona alguns sinos e assobios?

+1

+1

+1

eu tenho que listar os objetos de balde s3 que são modificados entre duas datas, ex. 08/06/2019 a 11/06/2019

alguma ideia de alguém?

aws s3api list-objects --bucket "BUCKET" --prefix "OPTIONAL" --query "Contents[?LastModified>='2019-06-08'][].{Key: Key,LastModified: LastModified}" e, em seguida, use JQ ou sua ferramenta preferida para filtrar após 11/06/2019

Isso não elimina chamadas de API. Essas consultas são do lado do cliente

Em Ter, 11 de junho de 2019, 14h07 willstruebing [email protected]
escreveu:

aws s3api list-objects --bucket "BUCKET" --prefix "OPTIONAL" --query
"Conteúdo [? LastModified> = '2019-06-08'] []. {Key: Key, LastModified:
LastModified} "e, em seguida, use JQ ou sua ferramenta preferida para filtrar após
11/06/2019

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/aws/aws-cli/issues/1104?email_source=notifications&email_token=AABLGMW5AFAU5BUNM7FEMZ3PZ7SV3A5CNFSM4A2VNZ2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXOALCY#issuecomment-500958603 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AABLGMVTIZDPPIEUK2CZR6TPZ7SV3ANCNFSM4A2VNZ2A
.

@dmead concordo totalmente. No entanto, a funcionalidade para fazer a filtragem do lado do servidor não existe atualmente (acho que é por isso que tantas pessoas acabam neste post em particular), então esta é a única solução alternativa que conheço para concluir a tarefa em questão. Você tem uma maneira de fazer no lado do servidor ou isso é apenas uma observação sobre a solução proposta? Eu adoraria ouvir informações sobre como fazer isso E reduzir a quantidade de chamadas de API.

Se você tiver tempo, eu consideraria a seleção de metadados em Atenas. eu
Eu mesmo não tive a chance, mas parecia uma solução possível.

Na quarta-feira, 12 de junho de 2019 às 10:28 willstruebing [email protected]
escreveu:

@dmead https://github.com/dmead Concordo totalmente. No entanto, o
funcionalidade para fazer a filtragem do lado do servidor não existe atualmente (eu acho
é por isso que tantas pessoas acabam neste post em particular), então este é o
única solução alternativa que conheço para concluir a tarefa em questão. Você tem um
maneira de fazer isso do lado do servidor ou isso é apenas uma observação sobre a proposta
solução? Eu adoraria ouvir sugestões sobre como fazer isso E reduzir a quantidade de
Chamadas de API.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/aws/aws-cli/issues/1104?email_source=notifications&email_token=AABLGMTQZD6OWVH4KDMSJPLP2EBY7A5CNFSM4A2VNZ2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXQTN3Y#issuecomment-501298927 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AABLGMRLA5OYSYGEYNPUY5DP2EBY7ANCNFSM4A2VNZ2A
.

+24

Todos aprovando isso, arquivar com o AWS CLI não ajuda. O AWS CLI está vinculado ao S3. Arquivo com a equipe S3, em vez de um github de ferramenta, se você quiser consertar: P

@ mike-bailey OK, e como faço isso?

Se fosse eu pessoalmente, eu arquivaria um tíquete da AWS para que ele chegue à equipe de serviço. Mas eu não trabalho para a AWS. Eu só sei que comentar '+1' sobre isso não vai ser a mudança.

Existe uma maneira de fazer isso com o s3api e a função --query. Isso é testado em OSX
aws s3api list-objects --bucket "bucket-name" --query 'Contents [? LastModified> = 2016-05-20 ] []. {Key: Key}'
você pode filtrar usando jq ou grep para fazer o processamento com as outras funções s3api.

Editar: não tenho certeza por que eles não estão aparecendo, mas você tem que usar crases para cercar a data que você está consultando

Certifique-se de que possui a versão mais recente de awscli antes de tentar esta resposta. Eu atualizei
awscli 1.11.47 -> 1.16.220
e fez a temida filtragem do lado do cliente, mas funcionou.
1 para filtragem do lado do servidor.

+1

+1

Por favor, leia o tópico, +1 não faz nada

Você não pode fazer isso facilmente, mas enterrada nesses comentários está a seguinte dica:

 aws s3api list-objects --bucket "bucket-name" --query 'Contents[?LastModified>=`2016-05-20`][].{Key: Key}'

Este ainda é do lado do cliente e realizará muitas solicitações.

Conforme observado anteriormente, porém, ele lida com isso do lado do cliente. Então, você ainda pode potencialmente acertar o balde com chamadas.

A filtragem deve ser do lado do servidor e é uma necessidade básica, eu acho.

Aqui está um exemplo usando o aws s3 sync para que apenas novos arquivos sejam baixados. Ele combina os registros em um arquivo de registro e remove os comentários antes de salvar o arquivo. Você pode então usar grep e coisas para obter dados de log. No meu caso, precisei contar acessos exclusivos para um arquivo específico. O código abaixo foi adaptado deste link: https://shapeshed.com/aws-cloudfront-log/ O comando sed também funciona no Mac e é diferente do que está no artigo. Espero que isto ajude!

aws s3 sync s3://<YOUR_BUCKET> .
cat *.gz > combined.log.gz
gzip -d combined.log.gz
sed -i '' '/^#/ d' combined.log

# counts unique logs for px.gif hits
grep '/px.gif' combined.log | cut -f 1,8 | sort | uniq -c | sort -n -r

# above command will return something like below. The total count followed by the date and the file name.
17 2020-01-02 /px.gif
 9 2020-01-03 /px.gif

Eu sei que é um problema antigo, mas para deixar uma solução elegante aqui:

aws s3api list-objects --output = text --query "Conteúdo [? LastModified> = <DATE_YOU_WANT_TO_START> ]. {Key: Key}"

Esta página foi útil?
0 / 5 - 0 avaliações