bash globstar matching


17

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 globstaropção 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.extexcluído desta lista?

O manual do Bash diz isso sobre globstar:

Se definido, o padrão '**' usado em um contexto de expansão de nome de arquivo corresponderá a todos os arquivos e zero ou mais diretórios e subdiretórios. Se o padrão for seguido por um '/', apenas diretórios e subdiretórios corresponderão.

" Zero " neste parágrafo me deixa com a impressão de que dir/file.extdeveria ter sido incluída; a menos que eu esteja perdendo alguma coisa.


2
Qual é esse personagem? ɀ?
Slm

2
Qual versão do bash, em que plataforma? Não consigo reproduzir isso com o bash 4.2.37 no Debian wheezy ou o bash 4.1.5 no Debian squeeze. @slm unicode ɀou Wikipedia
Gilles 'SO- stop

1
@ Gilles Isso é um prompt?
slm

5
slm, sim! ɀé apenas um caractere usado aqui para distinguir prompt. Alguns usuários preferem o personagem £ou em vez de $:). Originalmente, ɀum caractere 'z' criado para uma notação especial de idioma Africano :-)
Slyx

1
"O lançamento do GNU bash, versão 3.2.53 (1) (x86_64-apple-darwin13)" enviado com o OS X 10.9 tem esse comportamento.
Natevw 31/03

Respostas:


8

Eu acho que isso se refere apenas ao nível do subdiretório. **sem /fósforos

  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 superior ao qual **se aplica é correspondido.

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


Sim, é exatamente o meu substituto, simplesmente não parece bonito. ;-)
Vlad GURDIGA

9

Isso funciona como o 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

De fato, as versões listadas acima são tudo o que eu testei. Em outras palavras, não encontrei uma versão 4 do Bash onde ela não funciona. A opção globstarfoi adicionada no Bash 4.0, consulte ALTERAÇÕES . Nas versões mais antigas, o comando shopt -s globstardeve retornar um erro.

Testes

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

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

2. **/*.ext jogos 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

1
Esta é a resposta certa. O OP esqueceu de definir shopt -s globstar.
CS Pei

4

Parece-me que você desligou o globstar. Pode ser ativado 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 desativado, ** acaba se comportando como *, obtendo dir/**/*.exto mesmo resultado quedir/*/*.ext

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

o que às vezes me faz pensar que a globstar está ligada

verifique sua configuração atual da globstar assim:

shopt | grep globstar

1
Você pode verificar uma configuração de opção de shell diretamente, como em shopt globstar.
Benjamin W.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.