Você pode fazer isso apenas com curingas de shell. Construa um padrão com progressivamente mais níveis de diretório.
pattern='*'
set -- $pattern
while [ $# -ne 1 ] || [ "$1" != "$pattern" ]; do
for file; do
…
done
pattern="$pattern/*"
set -- $pattern
done
Isso perde os arquivos de pontos. Use FIGNORE='.?(.)' no ksh, shopt -s dotglob no bash ou setopt glob_dots no zsh para incluí-los.
Advertências:
- Isso explodirá a memória se houver muitos arquivos.
- Isso atravessa links simbólicos para diretórios de forma recursiva.
Se você quiser escolher a ordem ou diretórios e não diretórios, e o desempenho não é crítico, você pode fazer duas passagens e testar [ -d "$file" ] em cada passagem.