du | sort | awk = dusa

Segunda-feira, 17/03/2008 at 20:18 (Papo Geek, Para me lembrar...) (, , , , , , )

Por diversos motivos, vira e mexe, preciso saber quanto de espaço os diretórios estão utilizando em uma partição – na maioria das vezes preciso disso para procurar ‘vilões’ que eu mesmo criei, em outras palavras, pasta para enxugar e liberar algum espaço em disco.

Para descobrir os ladrões de espaço o utilitário de linha de comando ‘du‘ (disk usage) é uma grande ferramenta. Não vou contar a vida do du em detalhes, iniciarei com:

- estando no diretório de onde quero partir a caça pelos subdiretórios gulosos, utilizo:
du -sb */

que produz uma saída resumida (-s) de cada diretório com tamanhos apresentados em bytes (-b)

- aliando a saída deste comando ao ‘sort‘ a caça pode ser um tanto facilitada:
du -sb */ | sort -n
faz com que a saída seja apresentada com classificação ascendente de tamanhos, veja:

899990  explore2fs-1.07/
1335616 cpuz_144/
2450182 Recycled/
7498439 znerocache/
8130560 mssql/
32694454        trampos-senega/
53632492        palmOne/
149473543       trampos-sinergy/
277395319       wallpapers/
391518821       myDocs/
401388559       zdev/
462561819       xxx/
472861328       Arquivos de programas/
619498235       musicas/
1844380074      download/
2572069071      games/

Legal, mas está difícil de ler os tamanhos assim..

E se for utilizado o parâmetro -h no du?

Instruir o du a gerar uma saída legível ao homem (human readable) resolve o problema do formato dos números, mas gera outro: o sort não irá fazer a classificação corretamente (os equívocos foram destacados) – comando utilizado: du -sh */ | sort -n

1,3M    cpuz_144/
  1,8G    download/
2,4M    Recycled/
  2,5G    games/
7,4M    znerocache/
7,8M    mssql/
32M     trampos-senega/
54M     palmOne/
145M    trampos-sinergy/
266M    wallpapers/
374M    myDocs/
398M    zdev/
448M    xxx/
459M    Arquivos de programas/
591M    musicas/
  892K    explore2fs-1.07/

A classificação numérica está correta, mas a escalar não…

É aí que entra o awk (na verdade gawk). Não vou dar detalhes de funcionamento do awk, então havendo interesse nisso a documentação pode ser encontrada online aqui. Todavia, para não ficar completamente no ar o ‘programa’ feito no awk, vai uma breve conceituação:

  • o awk trabalha com ‘arquivos de dados’;
  • esses arquivos de dados geralmente são ser separados em campos (fields)
  • os campos de um arquivo de dados são acessados pelos identificadores $1, $2, $3,
    $0 representa ‘todos os campos‘ – uma linha, em outras palavras.
  • o separador padrão de campos é algum espaço em branco (seqüência de espaços ou tabs)
  • um identificador de campos pode ter seu valor alterado

No contexto do post o arquivo de dados é a saída do sort, claro que não é necessário criar um arquivo dessa saída para que o awk possa tratá-lo – basta redirecionar a saída para ele com mais um pipe.

O awk vai servir para formatar os números gerando uma saída mais amigável, mais legível, e portanto mais fácil e rápida de ser interpretada. O comando final fica assim:

du -sb */ | sort -n | gawk ‘{e=2; while (int($1/1024^e) > 0) { e++ }; s=$1/1024^(e-1); u=(e==2 ? “K” : (e==3 ? “M” : “G”)); $1=”"; printf(“%.1f%s\t%s\n”, s, u, $0)}’

Agora uma breve explicação de o que faz o que no comando awk (quebrando em linhas somente para facilitar a leitura/explicação):

gawk ‘{
e=2;
// ‘e’ de expoente: variável que guarda o expoente de 1024^e que irá servir para a divisão do tamanho
while (int($1/1024^e) > 0) { e++ };
// descobre quanto deve ser o expoente para normalizar o número
s=$1/1024^(e-1);
// ’s’ é o número no formato que interessa, ou seja, com característica (parte inteira) entre 1 e 999
u=(e==2 ? “K” : (e==3 ? “M” : “G”));

// define a unidade de medida (no máximo Giga Bytes)
$1=”";
// para que diretórios com espaço no nome não apareçam incompletos, anula-se o 1º campo para a seguir utilizar-se $0 na geração da saída
printf(“%.1f%s\t%s\n”, s, u, $0)
// gera a saída formatada
}’

Para facilitar a vida, pode-se criar um shell script chamado dusa (du + sort + awk) e colocá-lo em algum lugar providencial. O conteúdo desse arquivo nada mais é do que o encanamento dos 3 comandos, alterando-se
du -sb */ | sor…
por
du -sb “$@” | sor…
e executando-se
dusa */
a partir do diretório que deseja-se conhecer o tamanho dos subdiretórios – feito e testado no bash.

Só para constar, a saída gerada pelo comando completo é essa:

878,9K   explore2fs-1.07/
1,3M     cpuz_144/
2,3M     Recycled/
7,2M     znerocache/
7,8M     mssql/
31,2M    trampos-senega/
51,1M    palmOne/
142,5M   trampos-sinergy/
264,5M   wallpapers/
373,4M   myDocs/
382,8M   zdev/
441,1M   xxx/
451,0M   Arquivos de programas/
590,8M   musicas/
1,7G     download/
2,4G     games/

Comente