du | sort | awk = dusa
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/