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
Resposta
Acho que se refere apenas ao nível do subdiretório . **
sem /
corresponde a
-
todos os arquivos e diretórios
-
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
.
ɀ
?unicode ɀ
ou Wikipediaɀ
é 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: – )