it-swarm-pt.com

Como conto todos os arquivos recursivamente através de diretórios

Quero ver quantos arquivos existem nos subdiretórios para descobrir onde todo o uso do inode está no sistema. Mais ou menos como eu faria isso pelo uso do espaço

du -sh /*

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

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

Agradecimentos a Gilles e xenoterracide pelas 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 - enquanto o canal entrando no while estiver aberto (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 guia.

A quarta parte: find "$dir -f file" faz uma lista de todos os arquivos dentro do nome do diretório contidos 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 encerra 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 nele, para podermos contar todos eles usando wc -l. O resultado será semelhante a:

./dir1: 234
./dir2: 11
./dir3: 2199
...
67
Shawn J. Goff

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

17
herohuyongtao

Aqui está uma compilação de alguns comandos de listagem úteis (redefinidos 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 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
13
DolphinDream

Tentar:

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

como ponto de partida ou se você realmente deseja apenas recursar pelos 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
12
Cry Havok

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 os arquivos no diretório atual, você pode consultar outras respostas.

4
mouviciel

O 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
2
abeboparebop

Sei que estou atrasado para a festa, mas acredito que essa solução pura bash (ou outro Shell que aceite globos de estrela dupla) possa 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

resultado:

d1/:    302
d2/:    24
d3/:    640
...
2
jimmij

Faça uma tentativa:

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

Deve funcionar bem, a menos que os nomes de arquivos incluam novas linhas.

1

du --inodes

Não sei por que ninguém (inclusive eu) estava ciente de:

du --inodes
--inodes
      list inode usage information instead of block usage

Tenho certeza de que isso resolve o problema do OP. Comecei a usá-lo muito para descobrir onde está todo o lixo em minhas unidades enormes (e descarregá-lo em um disco antigo).

Mais informações

Se você NÃO deseja recorrer (o que pode ser útil em outras situações), adicione

-S, --separate-dirs
1
Sridhar Sarnobat

Se você tiver o ncdu instalado (indispensável quando desejar fazer uma limpeza), digite c em "Alternar a exibição das contagens de itens filhos". E C para "Classificar por itens".

1
Demi-Lune