Noms avec des caractères génériques

Description

gsutil accepte les caractères génériques d'URI. Par exemple, la commande :

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

copie tous les objets du sous-répertoire dont le nom commence par gs://bucket/data/abc suivi d'un nombre quelconque de caractères.

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

Caractères génériques répertoire par répertoire ou récursifs

Le caractère générique * ne correspond qu'à la fin du chemin dans un sous-répertoire. Par exemple, si votre bucket contient des objets nommés gs://bucket/data/abcd, gs://bucket/data/abcdef et gs://bucket/data/abcxyx ainsi qu'un objet dans un sous-répertoire (gs://bucket/data/abc/def), la commande gsutil cp ci-dessus rapporte les trois premiers noms d'objets mais pas le dernier.

Si vous souhaitez des correspondances couvrant des limites de répertoires, utilisez un caractère générique ** :

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

correspond aux quatre objets ci-dessus.

Notez que gsutil accepte les mêmes caractères génériques pour les objets et les noms de fichiers. Par exemple :

gsutil cp data/abc* gs://bucket

correspond à tous les noms dans le système de fichiers local.

Caractères génériques de bucket

Vous pouvez spécifier des caractères génériques pour les noms de buckets au sein d'un même projet. Exemple :

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

répertorie le contenu de tous les buckets dont le nom commence par data et se termine par .example.com dans le projet par défaut. L'option "-p" peut être utilisée pour spécifier un projet différent de celui par défaut. Exemple :

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

Vous pouvez également combiner des caractères génériques de nom de bucket et d'objet. Par exemple, la commande suivante supprime tous les fichiers .txt de n'importe quel bucket Cloud Storage du projet par défaut :

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

Autres caractères génériques

Outre *, vous pouvez utiliser les caractères génériques suivants :

?
Correspond à un seul caractère. Par exemple, "gs://bucket/??.txt" ne recherche que les objets dont deux caractères sont suivis de ".txt".
[caractères]
Correspond à l'un des caractères spécifiés. Par exemple, gs://bucket/[aeiou].txt recherche des objets contenant une seule voyelle suivie de .txt.
[plage caract]
Correspond à n'importe quel caractère de la plage. Par exemple, gs://bucket/[a-m].txt recherche des objets qui contiennent les lettres a, b, c, ... ou m, et se terminent par .txt.

Vous pouvez combiner des caractères génériques pour obtenir des correspondances plus efficaces, par exemple :

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

Comportements potentiellement inattendus lors de l'utilisation de caractères génériques

L'utilisation de caractères génériques peut entraîner divers comportements inattendus :

  1. Les interfaces système (telles que bash et zsh) peuvent tenter de développer les caractères génériques avant de transmettre les arguments à gsutil. Si le caractère générique est censé faire référence à un objet cloud, cela peut entraîner des erreurs "Introuvable" inattendues (par exemple, si l'interface système tente de développer le caractère générique gs://my-bucket/* sur la machine locale, ce qui ne rapporte aucune correspondance à un fichier local et entraîne l'échec de la commande).

    Notez que certaines interfaces système contiennent des caractères supplémentaires dans leurs jeux de caractères génériques. Par exemple, si vous utilisez zsh avec l'option extendedglob, # est traité comme un caractère spécial qui entre en conflit avec son utilisation dans le référencement d'objets avec des versions gérées (voir Restaurer les versions d'objet obsolètes pour obtenir un exemple).

    Pour éviter ces problèmes, placez l'expression entre des guillemets simples (sous Linux) ou guillemets doubles (sous Windows).

  2. Vous ne pouvez pas spécifier un nom de fichier contenant des caractères génériques, car gsutil tente de développer les caractères génériques plutôt que de les utiliser en tant que caractères littéraux. Par exemple, en exécutant la commande :

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

    gsutil interprète la partie [1] comme un caractère générique.

    Il existe un problème signalé de prise en charge du mode "brut" par gsutil, permettant d'utiliser des noms de fichiers contenant des caractères génériques. Toutefois, tant que cette compatibilité n'est pas mise en œuvre, il est impossible d'utiliser gsutil avec ces noms de fichiers. Vous pouvez utiliser un caractère générique pour nommer ces fichiers. Par exemple, vous pouvez remplacer la commande ci-dessus par :

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

    mais cette approche est potentiellement difficile à mettre en œuvre en général.

Comportement différent pour les fichiers "Dot" au sein du système de fichiers local

Conformément au comportement Unix standard, le caractère générique * ne correspond qu'aux fichiers qui ne commencent pas par un caractère . (pour éviter toute confusion avec les répertoires . et .. présents dans tous les répertoires Unix). gsutil applique le même comportement lorsque vous utilisez des caractères génériques sur un URI de système de fichiers, mais ne n'applique pas aux URI cloud. Par exemple, la commande suivante permet de copier tous les objets de gs://bucket1 vers gs://bucket2 :

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

Cependant, la commande suivante ne copie que les fichiers qui ne commencent pas par un ., du répertoire dir vers gs://bucket1 :

gsutil cp dir/* gs://bucket1

Facteur d'efficacité : utilisation de caractères génériques sur de nombreux objets

L'utilisation de caractères génériques comportant un préfixe de nom d'objet sans caractère générique est plus efficace, plus rapide et moins consommatrice de trafic réseau, par exemple :

gs://bucket/abc*.txt

que l'utilisation de caractères génériques comme première partie du nom d'objet. Exemple :

gs://bucket/*abc.txt

En effet, la requête pour gs://bucket/abc*.txt demande au serveur de renvoyer le sous-ensemble de résultats dont le nom d'objet commence par abc à la racine du bucket, puis gsutil filtre la liste des résultats pour les objets dont le nom se termine par .txt. En revanche, gs://bucket/*abc.txt demande au serveur la liste complète des objets à la racine du bucket, puis filtre les objets dont le nom se termine par abc.txt. Ce facteur d'efficacité est encore plus visible lorsque vous utilisez des buckets contenant des milliers d'objets ou plus. Il est parfois possible de configurer les noms de vos objets pour qu'ils correspondent aux modèles de correspondance de caractères génériques attendus, afin de profiter de l'efficacité des requêtes de préfixe côté serveur. Consultez par exemple, gsutil help prod pour obtenir un exemple concret d'utilisation.

Facteur d'efficacité : utilisation de caractères génériques au milieu du chemin d'accès

Supposons que vous disposiez d'un bucket avec les objets suivants :

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

Si vous exécutez la commande ci-dessous :

gsutil ls gs://bucket/*/obj5

gsutil renvoie une liste des buckets de premier niveau délimités par "/" puis une liste de buckets pour chaque sous-répertoire, soit un total de trois listes de buckets :

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

Plus le bucket contient de nombreuses listes de caractères génériques, plus l'opération est lente et onéreuse. Le nombre de listes de buckets requises augmente avec :

  • le nombre de composants génériques (par exemple, "gs://bucket/a? b/c*/*/d" comporte trois composants génériques) ;
  • le nombre de sous-répertoires correspondant à chaque composant ; et
  • le nombre de résultats (la pagination est effectuée à l'aide d'une requête GET pour 1 000 résultats, en spécifiant des marqueurs pour chacun d'eux).

Si vous souhaitez utiliser un caractère générique au milieu d'un chemin d'accès, essayez plutôt d'utiliser un caractère générique récursif, par exemple :

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

Cela correspond à plus d'objets que gs://bucket/*/obj5 (puisqu'il couvre plusieurs répertoires) mais est mis en œuvre à l'aide d'une requête de liste de buckets sans délimiteur (ce qui réduit le nombre de requêtes de bucket, bien que l'ensemble du bucket soit répertorié et filtré localement, ce qui peut nécessiter une quantité non négligeable de trafic réseau).