Univers Libre

trier numériquement la sortie d’un du -h

Written on 11 September 2010, 00:00 CEST
Tags: sysadmin.

Afficher la taille que prend un répertoire ainsi que ses sous répertoires est une tache assez courante, du moins pour un administrateur système. Cela se fait simplement avec la commande :

du -sh foo/*

Ou bien, si on veut avoir aussi les sous sous répertoires :

du -h --max-depth 2 foo/*

L'option -h permettant d'avoir la taille exprimé en kilo, méga, giga, etc…

Là où les choses se compliquent, c'est lorsqu'on veut trier numériquement le résultat par ordre décroissant. Si on fait un :

du -sh foo/* |sort -rn

le tri sera faussé du fait de la présence des lettres qui suivent la taille.

D'où l'astuce du jour : comment trier numériquement la sortie d'un du tout en ayant la taille exprimé en "human readable" ?

Si vous avez le paquet coreutils en version ≥ 7.5, vous êtes sauvé, sort implémente l'option -h qui répond exactement au problème :

du -sh foo/* |sort -rh

Dans le cas contraire (si vous êtes sur une Debian Lenny par exemple), c'est un peu moins simple.
En cherchant un peu sur le net, il existe un tas d'astuces différentes utilisant perl ou awk. Voici celle que j'utilise, qui me semble la moins tordue (mais un peu quand même) :

du -s foo/* |sort -rn |cut -f2 |xargs -d '\n' du -sh

Le principe est d'obtenir d'abord la liste des répertoires avec leur taille "brute", de trier cette liste, puis de refaire un du (avec -h cette fois) sur chaque répertoire de la liste).
Le fait d'exécuter 2 fois un du n'est pas super élégant point de performance, mais en pratique, comme le résultat du premier du est caché en mémoire, le second est très rapide.