Tenho esta estrutura de diretório:

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

e, com o globstar opção habilitada 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 excluído desta lista?

O manual Bash diz 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 correspondem.

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 perdendo algo.

Comentários

  • O que é esse personagem? ɀ?
  • Qual versão do bash, em qual plataforma? Não posso ' reproduzir isso com o bash 4.2.37 no Debian wheezy ou bash 4.1.5 no Debian squeeze. @slm unicode ɀ ou Wikipedia
  • @Gilles Isso é um prompt?
  • slm, sim! ɀ é apenas um caractere usado aqui para distinguir o prompt. Alguns usuários preferem o caractere £ ou em vez de $ :). Originalmente, ɀ a ' z ' caractere criado para uma notação especial de idioma africano: – )
  • " GNU bash, versão 3.2.53 (1) -release (x86_64-apple-darwin13) " fornecido com o OS X 10.9 tem este comportamento.

Resposta

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

  1. todos os arquivos e diretórios

  2. zero ou mais subdiretórios

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

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

Comentários

  • Sim, é exatamente meu substituto, só não parece bonito. 😉

Resposta

Isso funciona conforme o esperado nessas versões do Bash fornecidas 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 todas as que testei. Em outras palavras, não encontrei uma versão 4 do Bash que não funcione. A opção globstar foi adicionada no Bash 4.0, consulte ALTERAÇÕES . 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 

Comentários

  • este é o resposta correta. O OP esqueceu de definir shopt -s globstar.

Resposta

I me parece que você desligou / desligou o globstar. Ele pode ser ativado desta forma:

shopt -s globstar 

Não apenas não corresponderá a nenhum subdiretório, 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 globstar desativado, ** acaba se comportando exatamente 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 o Globstar está ligado

verifique sua configuração atual do Globstar, como isto:

shopt | grep globstar 

Comentários

  • Você pode verificar uma configuração de opção de shell diretamente, como em shopt globstar.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *