Como faço para contar todos os arquivos recursivamente através de diretórios

43

Eu quero ver quantos arquivos estão em subdiretórios para descobrir onde todo o uso do inode está no sistema. Mais ou menos como eu faria isso para uso de espaço

du -sh /*

que me dará o espaço usado nos diretórios fora do root, mas neste caso eu quero o número de arquivos, não o tamanho.

    
por xenoterracide 16.11.2010 / 12:02

8 respostas

55
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Graças a Gilles e xenoterracide para correções de segurança / compatibilidade.

A primeira parte: find -maxdepth 1 -type d retornará uma lista de todos os diretórios no diretório de trabalho atual. Isso é canalizado para ...

A segunda parte: while read -r dir; do inicia um loop while - desde que o pipe que entra no while esteja aberto (o que é até que toda a lista de diretórios seja enviada), o comando read colocará a próxima linha na variável "dir". Então continua ...

A terceira parte: printf "%s:\t" "$dir"; imprimirá a string em "$ dir" (que contém um dos nomes de diretório) seguido por uma aba.

A quarta parte: find "$dir -f file" faz uma lista de todos os arquivos dentro do nome do diretório em "$ dir". Esta lista é enviada para ..

A quinta parte: wc -l; conta o número de linhas que são enviadas para sua entrada padrão.

A parte final: done simplesmente termina o loop while.

Portanto, obtemos uma lista de todos os diretórios no diretório atual. Para cada um desses diretórios, geramos uma lista de todos os arquivos para que possamos contar todos usando wc -l . O resultado será parecido com:

./dir1: 234
./dir2: 11
./dir3: 2199
...
    
por 18.11.2010 / 00:55
13

Aqui está uma compilação de alguns comandos de listagem úteis (re-hashed com base no código de usuários anteriores):

Listar pastas com contagem de arquivos:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Listar pastas com contagem de arquivos diferente de zero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Listar pastas com contagem de subpastas:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Listar pastas com uma contagem de subpastas diferente de zero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Listar pastas vazias:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Listar pastas não vazias com contagem de conteúdo:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
    
por 16.05.2013 / 17:44
13

Teste find . -type f | wc -l , ele contará todos os arquivos no diretório atual, bem como todos os arquivos em subdiretórios. Note que todos os diretórios não serão contados como arquivos, apenas arquivos comuns.

    
por 17.09.2013 / 19:50
12

Tente:

find /path/to/start/at -type f -print | wc -l

como ponto de partida, ou se você realmente deseja apenas recorrer aos subdiretórios de um diretório (e pular os arquivos nesse diretório de nível superior)

find 'find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print' -type f -print | wc -l
    
por 16.11.2010 / 13:08
4

A solução a seguir conta o número real de inodes usados a partir do diretório atual:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Para obter o número de arquivos do mesmo subconjunto, use:

find . | wc -l

Para soluções que exploram apenas subdiretórios, sem levar em conta arquivos no diretório atual, você pode consultar outras respostas.

    
por 19.11.2010 / 20:42
2

OS X 10.6 engasga com o comando na resposta aceita, porque não especifica um caminho para find . Em vez disso, use:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
    
por 16.12.2014 / 00:46
2

Eu sei que estou atrasado para a festa, mas acredito que essa solução pura bash (ou outra shell que aceita glob star duplo) poderia ser muito mais rápida em algumas situações:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

saída:

d1/:    302
d2/:    24
d3/:    640
...
    
por 12.08.2015 / 22:57
1

Experimente:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Ele deve funcionar bem, a menos que nomes de arquivos incluam novas linhas.

    
por 16.11.2010 / 19:33