du que conta o número de arquivos / diretórios em vez de tamanho

7

Eu estou tentando limpar um disco rígido que tem todos os tipos de lixo acumulado ao longo dos anos. du ajudou a reduzir o uso do disco, mas a coisa toda ainda não é difícil, devido ao tamanho total, mas devido ao grande número de arquivos e diretórios no total.

Existe uma maneira de fazer algo como du , mas sem contar o tamanho do arquivo, mas sim o número de arquivos e diretórios? Por exemplo: um arquivo é 1 e um diretório é o número recursivo de arquivos / diretórios dentro dele + 1.

Edit: Eu deveria ter sido mais claro. Gostaria de saber não apenas o número total de arquivos / diretórios em / , mas também em /home , /usr etc e em seus subdiretórios, de forma recursiva, como du faz por tamanho.

    
por Jesse 20.04.2013 / 09:47

5 respostas

3

O seguinte script PHP faz o truque.

#!/usr/bin/php
<?php 

function do_scan($dir, $dev) {
  $total = 1;

  if (\filetype($dir) === 'dir' && \lstat($dir)['dev'] == $dev) {
    foreach (\scandir($dir) as $file) {
      if ($file !== '.' && $file !== '..') {
        $total += do_scan($dir . \DIRECTORY_SEPARATOR . $file, $dev);
      }
    }

    print "$total\t$dir\n";
  }

  return $total;
};

foreach (\array_slice($argv, 1) as $arg) {
  do_scan($arg, \lstat($arg)['dev']);
}

Coloque isso em um arquivo (digamos, " treesize "), chmod +x e execute com ./treesize . | sort -rn | less .

    
por 01.09.2013 / 16:18
7

A maneira mais fácil parece ser find /path/to/search -ls | wc -l

Find é usado para percorrer todos os arquivos e pastas.
-ls para listar (imprimir) todos os nomes. Este é um padrão e, se você o deixar, continuará funcionando da mesma forma em quase todos os sistemas. (Quase, já que alguns podem ter padrões diferentes). É um bom hábito explicitamente usar isso.

Se você acabou de usar a parte find /path/to/search -ls , ele imprimirá todos os arquivos e diretórios na tela.


wc é contagem de palavras. a opção -l diz para contar o número de linhas.

Você pode usá-lo de várias maneiras, por exemplo,

  • wc testfile
  • cat testfile | wc

A primeira opção permite abrir um arquivo e contar o número de linhas, palavras e caracteres naquele arquivo. A segunda opção faz o mesmo, mas sem o nome do arquivo, lê de stdin.


Você pode combinar comandos com um pipe | . A saída do primeiro comando será canalizada para a entrada do segundo comando. Assim find /path/to/search -ls | wc -l usa find para listar todos os arquivos e diretório e alimenta a saída para wc. Em seguida, conta o número de linhas.

(Uma outra alternativa teria sido 'ls | wc', mas é muito mais flexível e uma boa ferramenta para aprender.)

[Editar após comentário]

Pode ser útil combinar o find e o exec.

Por exemplo find / -type d ! \( -path proc -o -path dev -o -path .snap \) -maxdepth 1 -exec echo starting a find to count to files in in {} \; listará todos os diretórios em /, barra alguns que você não deseja pesquisar. Podemos acionar o comando anterior em cada um deles, gerando uma soma de arquivos por pasta em /.

No entanto:

  1. Isso usa a extensão específica do GNU -maxdepth.
    Ele funcionará no Linux, mas não em qualquer unix-a-like.
  2. Eu suspeito que você realmente queira um número de arquivos para cada subdiretório.
por 20.04.2013 / 11:47
2

Eu achei du --inodes útil, mas não tenho certeza de qual versão de du é necessária. No Ubuntu 17.10, os seguintes trabalhos:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Combine com | sort -nr para classificar em ordem decrescente pelo número de inodes contendo.

    
por 17.06.2018 / 18:51
1

Explore o fato de que diretórios e arquivos são separados por / . Esse script atende aos seus critérios, mas serve para inspirar uma solução completa. Você também deve considerar indexar seus arquivos com o locate.

geee: /R/tb/tmp
$ find  2>/dev/null | awk -F/ -f filez  | sort -n
files:  57
3       imagemagick
7       portage
10      colemak-1.0
25      minpro.com
42      monolith
80      QuadTree
117     themh
139     skyrim.stings
185     security-howto
292     ~t
329     skyrim
545     HISTORY
705     minpro.com-original
1499    transmission-2.77
23539   ugent-settings

>

$ cat filez
{
a[$2]++;     # $1= folder,  $2 = everything inside folder.
}

END {
        for (i in a) {
                if (a[i]==1) {files++;}
                else { printf "%d\t%s\n", a[i], i; }
        }
        print "files:\t" files
}

>

 $ time locate /  | awk -F/ -f /R/tb/tmp/filez  | sort -n
 files:  13
 2
 2       .fluxbox
 10      M
 11      BIN
 120     bin
 216     sbin
 234     boot
 374     R
 854     dev
 1351    lib
 2018    etc
 9274    media
 30321   opt
 56516   home
 93625   var
 222821  usr
 351367  mnt
 time: Real 0m17.4s  User 0m4.1s  System 0m3.1s
    
por 22.04.2013 / 12:47
0

Veja uma solução que usa o bash, inspirada em uma postagem do Unix & Linux .

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

Se houver algumas pastas das quais você não deseja ver os detalhes, como .git , exclua-as da lista com grep .

find . -type d |grep -v "./.git/.*" | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
    
por 09.08.2018 / 00:54