Isso funcionará no Bash 4:
ls -l {,**/}*.ext
Para que o glob de asterisco duplo funcione, a globstaropção precisa ser definida (padrão: ativado):
shopt -s globstar
De man bash:
globstar
Se definido, o padrão ** usado em uma expansão de nome de arquivo con‐
o texto corresponderá a 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.
Agora estou me perguntando se pode ter havido um bug no processamento globstar, porque agora usando simplesmente ls **/*.extestou obtendo resultados corretos.
Independentemente disso, olhei para a análise que kenorb fez usando o repositório VLC e encontrei alguns problemas com essa análise e em minha resposta imediatamente acima:
As comparações com a saída do findcomando são inválidas, pois a especificação -type fnão inclui outros tipos de arquivo (diretórios em particular) e os lscomandos listados provavelmente incluem . Além disso, um dos comandos listados,ls -1 {,**/}*.* - que parece ser baseado no meu acima, só exibe nomes que incluem um ponto para os arquivos que estão em subdiretórios. A pergunta do OP e minha resposta incluem um ponto, pois o que se busca são arquivos com extensão específica.
O mais importante, entretanto, é que há um problema especial ao usar o lscomando com o padrão globstar **. Muitas duplicatas surgem, pois o padrão é expandido pelo Bash para todos os nomes de arquivo (e nomes de diretório) na árvore que está sendo examinada. Após a expansão, o lscomando lista cada deles e seu conteúdo, se forem diretórios.
Exemplo:
Em nosso diretório atual está o subdiretório Ae seu conteúdo:
A
└── AB
└── ABC
├── ABC1
├── ABC2
└── ABCD
└── ABCD1
Nessa árvore, **expande para "AA / AB A / AB / ABC A / AB / ABC / ABC1 A / AB / ABC / ABC2 A / AB / ABC / ABCD A / AB / ABC / ABCD / ABCD1" (7 entradas) . Se você fizer echo **isso, será a saída exata que obterá e cada entrada será representada uma vez. No entanto , se você fizer ls **isso, irá gerar uma lista de cada uma dessas entradas. Basicamente, ele é ls Aseguido por ls A/ABetc., então A/ABé mostrado duas vezes. Além disso, lsseparará a saída de cada subdiretório:
...
<blank line>
directory name:
content-item
content-item
Portanto, o uso de wc -lconta todas aquelas linhas em branco e cabeçalhos de seção de nome de diretório, o que torna a contagem ainda mais difícil.
Este é outro motivo pelo qual você não deve analisarls .
Como resultado desta análise adicional, recomendo não usar o padrão globstar em qualquer circunstância que não seja iterar sobre uma árvore de arquivos desta maneira:
for entry in **
do
something "$entry"
done
Como comparação final, usei um repositório de origem Bash que tinha à mão e fiz o seguinte:
shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .
Eu costumava trmudar os espaços para novas linhas, o que só é válido aqui, já que nenhum nome inclui espaços. Eu costumava sedremover a liderança ./de cada linha de saída de find. Classifiquei a saída de, findpois normalmente ela não está classificada e a expansão de globs do Bash já está classificada. Como você pode ver, a única saída de difffoi a .saída do diretório atual por find. Quando o fiz, ls ** | wc -la saída tinha quase o dobro de linhas.
**/*.ext. Tem certeza de que funciona para você?