bash globstar matching

12

Eu tenho esta estrutura de diretórios:

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

e, com a opção globstar ativada no Bash, posso dizer:

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

Minha pergunta é: por que dir/file.ext está excluído dessa lista?

Manual de Bash diz isso sobre globstar :

If set, the pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/’, only directories and subdirectories match.

zero ” neste parágrafo, deixe-me com a impressão de que dir/file.ext deveria ter sido incluído; a menos que eu esteja com saudades de alguma coisa.

    
por Vlad GURDIGA 03.03.2014 / 00:01

3 respostas

5

Acho que se refere apenas ao nível do subdiretório. ** sem / corresponde

  1. todos os arquivos e diretórios

  2. zero ou mais subdiretórios

Mas isso não desaparece completamente. **/ significa que nenhum arquivo no diretório de nível mais alto ao qual ** se aplica é correspondido.

Você precisa de dir/*.ext dir/**/*.ext .

    
por 03.03.2014 / 00:12
8

Isso funciona como esperado nessas versões do Bash, conforme fornecido com as distribuições listadas:

  • 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

Na verdade, as versões listadas acima são tudo o que testei. Em outras palavras, eu não encontrei uma versão 4 do Bash onde ele não funciona. A opção globstar foi adicionada no Bash 4.0, veja MUDANÇAS . Em versões mais antigas, o comando shopt -s globstar deve retornar um erro.

Testes

1. dir/**/*.ext corresponde a dir/file.ext :

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

2. **/*.ext corresponde a file.ext :

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

Preparando o ambiente para reproduzir os testes acima:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
    
por 22.09.2014 / 12:47
3

Eu me parece que você teve / teve globstar desativado. Pode ser ligado assim:

shopt -s globstar

Não só não corresponderá a zero subdiretórios, mas também não corresponderá a dois subdiretórios:

$ 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

Com o globstar desligado, ** acaba se comportando como *, então dir/**/*.ext obtém o mesmo resultado que dir/*/*.ext

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

que às vezes me leva a pensar que globstar está em

verifique sua configuração atual de globstar assim:

shopt | grep globstar
    
por 08.10.2016 / 12:21