Como obter a distribuição de tamanhos de arquivo?

2

Gostaria de saber a distribuição de tamanhos de arquivo em um determinado diretório.

Por favor, note: distribuição de tamanhos de arquivo , não tamanho de um diretório . Isso significa que eu quero saber que existem 25 arquivos de 60 bytes, 50 arquivos de 12587 bytes, 2 arquivos de 57kbytes e assim por diante.

Pontos de bônus se os dados puderem ser coletados via linha de comando (por exemplo, em um sistema remoto) em um formato facilmente utilizável para produzir gráficos.

    
por Luke404 07.11.2012 / 11:57

3 respostas

5

Relacione os arquivos, extraia o tamanho em bytes da lista, classifique-o e conte a ocorrência de todos os tamanhos:

find /my/directory -type f -exec ls -l {} + | cut -d' ' -f5 | sort -n | uniq -c
  • não muito eficiente
  • se houver muitos arquivos, pode ser melhor salvar os resultados intermediários em um arquivo temporário, classificá-lo em outro arquivo temporário e, em seguida, "uniq"
  • aqui eu uso a classificação numérica para que a saída seja ordenada pelo tamanho do arquivo ascendente (legal), mas qualquer tipo será feito contanto que as linhas iguais sejam agrupadas
  • canalize os resultados em awk '{ print $1 "," $2 }' para obter um arquivo CSV a ser usado em sua ferramenta gráfica de escolha (até as ferramentas de planilha farão)
por 07.11.2012 / 11:57
3

Uma variante do Luke404 com o GNU encontra:

find . -type f -printf '%s\n' | sort -n | uniq -c
    
por 07.11.2012 / 16:06
1

Este código Perl pode ajudar:

@files = grep {-f} glob "*"; #List files in the current directory   
%files;  
for(@files)  
{  
  chomp (my $size = \'du -h \"$_\"');  
  $size=~ s/\s+.*//;  #Remove the file name from the output of du  
  $files{$size}++;  #  Add an entry to the hash  
}  
print "Size,Count\n"; # Print a header  
print "${\_},$files{$_}\n" for(keys %files); # Print info in CSV format  

Observe o seguinte:

  • Este código não tenta ordenar os arquivos por tamanho (isso provavelmente precisaria de uma sub-rotina por si só)
  • Estou usando du em vez do operador -s do Perl para ter uma saída legível.
  • Se você quiser listar o conteúdo de um diretório diferente do atual, substitua glob "*" por glob "$ARGV[0]/*" e forneça o nome do diretório necessário como um argumento de linha de comando.
  • Se você deseja listar o conteúdo de vários diretórios em um trabalho em lote, é possível salvar este código como list_dir.pl e ter um wrapper bash que faça algo assim:

    list_dir.pl dir1 > dir1_list.csv  
    list_dir.pl dir2 > dir2_list.csv
    
  • Como alternativa, o código pode ser modificado para aceitar vários diretórios como argumentos e bifurcar um processo para cada diretório pesquisado.

Eu estou supondo que você quer arquivos no diretório atual apenas um nível de profundidade (sem recursão).

    
por 07.11.2012 / 14:49

Tags