Embora o uso do find
comando possa ser útil aqui, o próprio shell fornece opções para atingir esse requisito sem ferramentas de terceiros. O bash
shell fornece uma opção estendida de suporte global, com a qual você pode obter os nomes dos arquivos em caminhos recursivos que correspondem às extensões desejadas.
A opção estendida é a extglob
que precisa ser definida usando a shopt
opção abaixo. As opções são ativadas com o -s
suporte e desativadas com o -u
sinalizador. Além disso, você pode usar mais algumas opções, ou seja, nullglob
nas quais um globo incomparável é varrido completamente, substituído por um conjunto de zero palavras. E globstar
isso permite recuperar através de todos os diretórios
shopt -s extglob nullglob globstar
Agora, tudo o que você precisa fazer é formar a expressão glob para incluir os arquivos de uma determinada extensão, que você pode fazer como abaixo. Usamos uma matriz para preencher os resultados globais porque, quando citados corretamente e expandidos, os nomes de arquivos com caracteres especiais permaneceriam intactos e não seriam quebrados devido à divisão de palavras pelo shell.
Por exemplo, para listar todos os *.csv
arquivos nos caminhos recursivos
fileList=(**/*.csv)
A opção **
é recursar pelas subpastas e *.csv
é uma expansão global para incluir qualquer arquivo das extensões mencionadas. Agora, para imprimir os arquivos reais, basta
printf '%s\n' "${fileList[@]}"
Usar uma matriz e fazer uma expansão entre aspas adequada é o caminho certo quando usado em scripts de shell, mas para uso interativo, você pode simplesmente usar ls
com a expressão glob como
ls -1 -- **/*.csv
Isso pode muito bem ser expandido para corresponder a vários arquivos, ou seja, arquivo que termina com várias extensões (ou seja, semelhante à adição de vários sinalizadores no find
comando). Por exemplo, considere um caso de necessidade de obter todos os arquivos de imagem recursivos, ou seja, de extensões *.gif
, *.png
e *.jpg
tudo o que você precisa é
ls -1 -- **/+(*.jpg|*.gif|*.png)
Isso poderia muito bem ser expandido para ter resultados negativos. Com a mesma sintaxe, pode-se usar os resultados da glob para excluir arquivos de determinado tipo. Suponha que você deseja excluir nomes de arquivos com as extensões acima, você pode fazer
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
A construção !()
é uma operação de negação para não incluir nenhuma das extensões de arquivo listadas dentro e |
é um operador de alternância da mesma forma que é usado na biblioteca Extended Regular Expressions para fazer uma correspondência OR dos globs.
Observe que esse suporte estendido a glob não está disponível no shell POSIX bourne e é puramente específico para as versões recentes do bash
. Portanto, se você está considerando a portabilidade dos scripts executados no POSIX e nos bash
shells, essa opção não está correta.