Nomes de caractere curinga

Descrição

O gsutil é compatível com caracteres curinga de URI. Por exemplo, o comando:

gsutil cp gs://bucket/data/abc* .

copiará todos os objetos que começam com gs://bucket/data/abc seguido de qualquer número de caracteres dentro desse subdiretório.

Diretório por diretório vs. Caracteres curinga recursivos

O caractere curinga "*" corresponde apenas ao final de um caminho dentro de um subdiretório. Por exemplo, se o bucket contiver objetos chamados gs://bucket/data/abcd, gs://bucket/data/abcdef e gs://bucket/data/abcxyx, além de um objeto em um subdiretório (gs://bucket/data/abc/def), o comando cp do gsutil acima corresponderia aos três primeiros nomes de objeto, mas não ao último.

Se você quiser que as correspondências ultrapassem os limites do diretório, use um caractere curinga "**":

gsutil cp gs://bucket/data/abc** .

corresponderá aos quatro objetos acima.

O gsutil é compatível com os mesmos caracteres curinga para objetos e nomes de arquivos. Assim, por exemplo:

gsutil cp data/abc* gs://bucket

corresponderá a todos os nomes no sistema de arquivos local. A maioria dos shells de comando também é compatível com caracteres curinga. Portanto, se você executar o comando acima, provavelmente, o shell está expandindo as correspondências antes de executar o gsutil. No entanto, a maioria dos shells não é compatível com caracteres curinga recursivos ('**'). Para esses shells, use o suporte a caracteres curinga do gsutil adicionando aspas simples aos argumentos, o que evita que eles sejam interpretados pelo shell antes de serem transmitidos ao gsutil:

gsutil cp 'data/abc**' gs://bucket

Caracteres curingas de bucket

Você pode especificar caracteres curinga para nomes de bucket em um único projeto. Exemplo:

gsutil ls gs://data*.example.com

listará o conteúdo de todos os buckets cujos nomes começam com "data" e terminam com ".example.com" no projeto padrão. A opção -p pode ser usada para especificar um projeto diferente do padrão. Exemplo:

gsutil ls -p other-project gs://data*.example.com

Também é possível combinar caracteres curinga de nome de bucket e objeto. Por exemplo, este comando removerá todos os arquivos ".txt" de qualquer um dos buckets do Cloud Storage no projeto padrão:

gsutil rm gs://*/**.txt

Outros caracteres curinga

Além de "*", você pode usar estes caracteres curinga:

?
Corresponde a um único caractere. Por exemplo, "gs://bucket/??.txt" só corresponde a objetos com dois caracteres seguidos por .txt.
[caracteres]
Corresponde a qualquer um dos caracteres especificados. Por exemplo, "gs://bucket/[aeiou].txt" corresponde a objetos que contêm um único caractere de vogal seguido de .txt.
[intervalo de caracteres]
Corresponde a qualquer um dos intervalos de caracteres. Por exemplo, "gs://bucket/[am].txt" corresponde a objetos que contêm letras a, b, c, ... ou m e terminam com .txt.

É possível combinar caracteres curinga para fornecer correspondências mais poderosas, por exemplo:

gs://bucket/[a-m]??.j*g

Potencial comportamento inesperado ao usar caracteres curinga

Algumas maneiras de usar caracteres curinga podem resultar em comportamentos inesperados:

  1. Os shell (como bash e zsh) podem tentar expandir caracteres curinga antes de passar os argumentos para o gsutil. Se o caractere curinga deveria se referir a um objeto de nuvem, isso pode resultar em erros "Não encontrado" (por exemplo, se o shell tenta expandir o curinga "gs://my-bucket/*" na máquina local, sem arquivos locais e com falha no comando).

    Algumas shells incluem caracteres adicionais nos conjuntos de caracteres curinga. Por exemplo, se você usar zsh com a opção extendedglob ativada, ele tratará "#" como um caractere especial, que entra em conflito com o uso desse caractere ao referenciar objetos com controle de versão. Consulte Versões de ajuda do gsutil para mais detalhes.

    Para evitar esses problemas, coloque a expressão curinga entre aspas simples (no Linux) ou aspas duplas (no Windows).

  2. A tentativa de especificar um nome de arquivo que contenha caracteres curinga não funcionará, porque o gsutil tentará expandi-los em vez de usá-los como caracteres literais. Por exemplo, execute o comando:

    gsutil cp './file[1]' gs://my-bucket
    

    fará com que o gsutil tente corresponder à parte '[1]' como um caractere curinga.

    Há uma solicitação em aberto para oferecer suporte ao modo "bruto" e fazer com que o gsutil forneça uma maneira de trabalhar com nomes de arquivos que contêm caracteres curinga. No entanto, até que o suporte seja resolvido, não há uma boa maneira de usar gsutil com esses nomes de arquivo. É possível usar um caractere curinga para nomear esses arquivos, por exemplo, substituindo o comando acima por:

    gsutil cp './file*1*' gs://my-bucket
    

    mas, em geral, é difícil usar essa abordagem.

Comportamento diferente para arquivos "Dot" no sistema de arquivos local

De acordo com o comportamento padrão do Unix, o caractere curinga "*" corresponde somente aos arquivos que não começam com "." (para evitar confusão com os diretórios "." e ".." presentes em todos os diretórios Unix). O gsutil apresenta esse mesmo comportamento ao usar caracteres curinga em um URI do sistema de arquivos, mas não em URIs da nuvem. Por exemplo, o seguinte comando copiará todos os objetos de gs://bucket1 para gs://bucket2:

gsutil cp gs://bucket1/* gs://bucket2

mas o comando a seguir copiará apenas os arquivos que não começam com um "." do diretório "dir" para gs://bucket1:

gsutil cp dir/* gs://bucket1

Análise da eficiência: como usar caracteres curingas em muitos objetos

É mais eficiente, mais rápido e ocupa menos a rede usar caracteres curinga com um prefixo de nome de objeto que não seja curinga, como:

gs://bucket/abc*.txt

do que usar curingas como a primeira parte do nome do objeto, como:

gs://bucket/*abc.txt

Isso ocorre porque a solicitação para "gs://bucket/abc*.txt" pede que o servidor retorne o subconjunto de resultados com nomes de objeto que começam com "abc" na raiz do bucket. Em seguida, o gsutil filtra a lista de resultados para nomes que terminam com ".txt". Por outro lado, "gs://bucket/*abc.txt" solicita ao servidor a lista completa de objetos na raiz do bucket e filtra os objetos com nomes terminados em "abc.txt". Essa consideração de eficiência se torna cada vez mais perceptível quando você usa buckets que contêm milhares (ou mais) de objetos. Às vezes, é possível configurar os nomes dos seus objetos para se ajustarem aos padrões esperados de correspondência de caracteres curinga para aproveitar a eficiência de fazer solicitações de prefixo do servidor. Consulte, por exemplo, gsutil help prod para um exemplo de caso de uso concreto.

Análise da eficiência: como usar caracteres curinga intermediários

Suponha que você tenha um bucket com estes objetos:

gs://bucket/obj1
gs://bucket/obj2
gs://bucket/obj3
gs://bucket/obj4
gs://bucket/dir1/obj5
gs://bucket/dir2/obj6

Se você executar o comando:

gsutil ls gs://bucket/*/obj5

O gsutil executará uma listagem de buckets de nível superior /-delimited e uma listagem de buckets para cada subdiretório, totalizando três listagens:

GET /bucket/?delimiter=/
GET /bucket/?prefix=dir1/obj5&delimiter=/
GET /bucket/?prefix=dir2/obj5&delimiter=/

Quanto mais listagens de bucket seu caractere curinga exigir, mais lento e mais caro será. O número de listagens de bucket necessárias aumenta dessa maneira:

  • o número de componentes com caracteres curinga (por exemplo, "gs://bucket/a? b/c*/*/d" tem três componentes curinga);
  • o número de subdiretórios que correspondem a cada componente; e
  • o número de resultados (a paginação é implementada usando uma solicitação GET por 1.000 resultados, especificando marcadores para cada um).

Se você quiser usar um curinga intermediário, em vez disso, prefira um curinga recursivo, por exemplo:

gsutil ls gs://bucket/**/obj5

Isso corresponderá a mais objetos do que "gs://bucket/*/obj5" (já que abrange diretórios), mas é implementado usando uma solicitação de listagem de bucket sem delimitador. Há menos solicitações de bucket, mas com uma listagem de todo o bucket e filtro local, podendo exigir uma quantidade incomum de tráfego de rede.