correspondance bash globstar

17

J'ai cette structure de répertoire:

~/tmp/globstar ɀ  find dir -type f
dir/file.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

et, avec l' globstaroption activée dans Bash, je peux dire:

~/tmp/globstar ɀ  ls -1 dir/**/*.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

Ma question est: pourquoi est dir/file.extexclu de cette liste?

Le manuel de Bash dit ceci à propos deglobstar :

S'il est défini, le modèle «**» utilisé dans un contexte d'extension de nom de fichier correspondra à tous les fichiers et à zéro ou plusieurs répertoires et sous-répertoires. Si le modèle est suivi d'un '/', seuls les répertoires et sous-répertoires correspondent.

« Zéro » dans ce paragraphe m'a donné l'impression qu'il dir/file.extaurait dû être inclus; sauf si j'espère que je manque quelque chose.

Vlad GURDIGA
la source
2
Quel est ce personnage? ɀ?
slm
2
Quelle version de bash, sur quelle plateforme? Je ne peux pas reproduire cela avec bash 4.2.37 sur Debian Wheezy ou bash 4.1.5 sur Debian squeeze. @slm unicode ɀou Wikipedia
Gilles 'SO- arrête d'être méchant'
1
@Gilles Est-ce une invite?
slm
5
slm, oui! ɀest juste un caractère utilisé ici pour distinguer l'invite. Certains utilisateurs préfèrent le caractère £ou au lieu de $:). A l'origine, ɀun caractère 'z' créé pour une notation spéciale en langue africaine :-)
Slyx
1
«GNU bash, version 3.2.53 (1) -release (x86_64-apple-darwin13)» fourni avec OS X 10.9 a ce comportement.
natevw

Réponses:

8

Je suppose que cela se réfère uniquement au niveau du sous-répertoire. **sans /allumettes

  1. tous les fichiers et répertoires

  2. zéro ou plusieurs sous-répertoires

Mais il ne disparaît pas complètement. **/signifie qu'aucun fichier du répertoire de plus haut niveau auquel **s'applique ne correspond.

Vous en avez besoin dir/*.ext dir/**/*.ext.

Hauke ​​Laging
la source
Ouais, c'est exactement mon repli, ça n'a pas l'air joli. ;-)
Vlad GURDIGA
9

Cela fonctionne comme prévu dans ces versions de Bash fournies avec les distributions répertoriées:

  • 4.1.2 (1) - CentOS 6.5
  • 4.1.5 (1) - Debian 6.0.10
  • 4.1.10 (4) - Cygwin 1.7.31
  • 4.2.46 (1) - CentOS 7.1
  • 4.3.11 (1) - Ubuntu 14.04.1
  • 4.3.30 (1) - Debian 8.1

En fait, les versions répertoriées ci-dessus sont tout ce que j'ai testé. En d'autres termes, je n'ai pas trouvé de version 4 de Bash où cela ne fonctionne pas. L'option a globstarété ajoutée dans Bash 4.0, voir MODIFICATIONS . Dans les anciennes versions, la commande shopt -s globstardevrait renvoyer une erreur.

Les tests

1. dir/**/*.ext correspond dir/file.ext:

~/tests$ ls -1 dir/**/*.ext
dir/file.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

2. **/*.ext correspond file.ext:

~/tests$ cd dir
~/tests/dir$ ls -1 **/*.ext
file.ext
subdir1/file.ext
subdir2/file.ext

Préparation de l'environnement pour reproduire les tests ci-dessus:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
pabouk
la source
1
c'est la bonne réponse. L'OP a oublié de régler shopt -s globstar.
CS Pei
4

Il me semble que vous avez / avait éteint globstar. Il peut être activé comme ceci:

shopt -s globstar

Non seulement il ne correspondra à aucun sous-répertoire, mais il ne correspondra pas non plus à deux sous-répertoires:

$ find dir -type f #the same as yours except with a directory inside one of the subdirectories
dir/file.ext
dir/subdir1/file.ext
dir/subdir1/subsubdir/file.ext
dir/subdir2/file.ext
$ shopt -u globstar #turn globstar off
$ #will only show files in subdirectories
$ #will not show files in dir or in subsubdir
$ echo dir/**/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext
$ shopt -s globstar #turn globstar on
$ #will show all four files
$ echo dir/**/*.ext
dir/file.ext dir/subdir1/file.ext dir/subdir1/subsubdir/file.ext dir/subdir2/file.ext

Avec globstar désactivé, ** finit par se comporter comme *, donc dir/**/*.extobtient le même résultat quedir/*/*.ext

$ echo dir/*/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext

ce qui me fait parfois penser que globstar est sur

vérifiez votre paramètre globstar actuel comme ceci:

shopt | grep globstar
Alex028502
la source
1
Vous pouvez vérifier directement un paramètre d'option shell, comme dans shopt globstar.
Benjamin W.