Find : classer par taille les résultat d’une recherche avec AWK

Depuis quelques années maintenant, je suis un grand fan de la ligne de commande qui permet de gagner beaucoup de temps une fois maîtrisée. L’autre avantage de maîtriser la ligne de commande, c’est que sur n’importe quelle distribution ou serveur sous Linux, vous devriez vous y retrouver. J’aime tellement ça que même dans Laravel, j’utilise beaucoup la ligne de commande pour faire tourner certains programmes maisons directement dans le framework. Clairement, ça vaut le coup d’apprendre à manier la ligne de commande. Pour aller plus loin, je vous ai aussi récemment présenté la commande grep qui permet de rechercher facilement du texte et de sortir la liste des fichiers qui contiennent l’occurrence.

Aujourd’hui, nous allons reparler de la commande find que je vous avais présenté ici, mais cette fois, on va aller encore un peu plus loin dans son utilisation. Je souhaite classer les fichiers d’un dossier selon leur taille du plus grand au plus petit. Ce n’est pas tout car j’aimerais aussi classer par taille les fichiers d’un dossier, mais de manière récursive donc en classant l’ensemble des fichiers contenus dans les sous-répertoires et ce bien sûr en une seule commande dans le terminal. 

Il y a bien la commande :

ls -lS /chemin/du/dossier

Mais celle-ci ne me convient pas pour plusieurs raisons :

  • Pas de récursivité.
  • Je veux le chemin complet des fichiers qui s’affichent dans la réponse.
  • Je veux que la valeur de la taille de chaque fichier soit facilement lisible par un humain et ne pas avoir la taille des fichier en nombre d’octets.

Trier et classer les fichiers d’un répertoire par taille avec find et awk

Ne perdons pas de temps et attaquons directement dans le dur, voici ma petite commande fétiche que je vous détaillerai juste après :

find /chemin/du/dossier -type f -exec du -h {} \; | sort -hr | awk '{printf "%s\t%s\n", $1, $2}'

Il est bien sur possible de lui préciser de travailler sur un type de fichiers en particulier, ici, ce serait sur les .txt et .csv :

find /chemin/du/dossier -type f \( -iname "*.txt" -o -iname "*.csv" \) -exec du -h {} \; | sort -hr | awk '{printf "%s\t%s\n", $1, $2}' 

Cette commande est donc une commande shell utilisée pour rechercher des fichiers avec des extensions spécifiques dans un dossier spécifique, les trier par taille décroissante et afficher leur taille et leur chemin complet avec bien évidemment leur nom.

Pour bien comprendre voici une petite explication point par point de cette commande :

  • find /chemin/du/dossier : Cette partie de la commande utilise la commande find pour rechercher des fichiers dans le dossier spécifié.
  • -type f : Cette option spécifie que nous recherchons uniquement des fichiers et non des répertoires.
  • ( -iname « .txt » -o -iname « .csv » ) : Valable seulement pour la deuxième commande d’exemple un peu plus complexe. Cette partie de la commande utilise des expressions régulières pour spécifier les types de fichiers à rechercher, dans ce cas, les fichiers avec l’extension « .txt » ou « .csv ». L’option -iname spécifie de rechercher des fichiers avec une correspondance insensible à la casse.
  • -exec du -h {} \; : Cette option utilise la commande  » du  » pour afficher la taille des fichiers trouvés en utilisant un format facile à lire pour les humains, en l’occurence le paramètre -h. Le {} représente chaque fichier trouvé, et le \; termine la commande.
  • | : Cette partie de la commande utilise un pipeline pour transmettre les résultats de la commande find à la commande sort.
  • sort -hr : Cette commande trie les résultats en fonction de leur taille et en ordre décroissant pour avoir les fichiers les plus gros en haut avec le paramètre -r.
  • | : Comme au-dessus, cette partie de la commande utilise un autre pipeline pour transmettre les résultats triés à la commande awk.
  • awk ‘{printf « %s\t%s\n », $1, $2}’: Cette commande utilise awk pour formater la sortie en deux colonnes : la taille du fichier en premier et le chemin avec le nom du fichier en second. La commande printf spécifie le format de sortie en utilisant une tabulation \t pour séparer les deux colonnes.

J’écris ces articles pour stocker mes recherches surtout ce qui marche par rapport à mes besoins personnels au quotidien, mais j’espère que si vous êtes arrivés ici cette ligne de commande vous aura donné satisfaction. Si vous avez des améliorations ou que vous voulez en parler n’hésitez pas à me laisser un commentaire !

2 réflexions au sujet de “Find : classer par taille les résultat d’une recherche avec AWK”

  1. Bonjour,

    Les répertoires/fichiers voient leur nom tronqué au premier espace dans la sortie avec votre commande. En retirant la commande « awk » à la fin, la sortie me semble correcte, la seule différence que je note étant que les noms ne sont pas tronqués (la tabulation est déjà présente dans la sortie naturelle de « du »).

    Pour la commande « find », on peut utiliser « \+ » au lieu de « \; » quand il n’y a « pas trop » de fichiers, pour optimiser un peu (ça lancera une unique commande « du » au lieu d’une par fichier).

    Répondre
  2. Bonjour,
    Voici une autre commande possible :

    find . -type f -printf « %kK %p\n » | sort -nr | numfmt –from=iec –to=iec

    %kK fait l’équivalent d’un « du -k » (espace utilisé en KiB) (il faut ajouter le « K » soi-même)
    %p nom du fichier
    numfmt permet de convertir les tailles de kilo vers Mega, Giga, etc.

    C’est 43 fois plus rapide sur ma machine, je pense que ce sont les appels répétés à « du » qui ralentissent ta version.

    Pour avoir la taille du fichier à la place de l’espace utilisé :
    find . -type f -printf « %s %p\n » | sort -nr | numfmt –to=iec

    Répondre

Laisser un commentaire