Dans le cadre du débuggage d\’un programme C, j\’ai été amené à écrire dans un fichier plus de 5 millions de valeurs numériques dans le but de les trier ensuite et de supprimer les doublons (\ »Ah le mec qui debug avec des printf()!\ » – Ouai ben des fois y\’a que ça d\’efficace!) . Une fois ce fichier généré, soit environ 40Mo, je me suis posé la question de l\’outil à utiliser pour effectuer les opérations dont j\’avais besoin. J\’ai pensé à plusieurs choses :
- Ouvrir le fichier avec LibreOffice Calc mais il se trouve que celui-ci est limité à un peu plus de 100 000 lignes et ne permet donc pas d\’exploiter mon fichier.
- Insérer en base de données les valeurs et effectuer les opérations en SQL. Problème : Il faut une base de données à disposition d\’une part et si c\’est le cas, MySQL via PhpMyAdmin refuse d\’importer le fichier car il est, semble-t-il, trop volumineux.
- Écrire un programme qui lit le fichier, stocke toutes la valeurs dans un tableau et effectue les opérations nécessaires. Seulement voilà, on n\’a pas forcément l\’envie ni le temps d\’écrire un programme pour un traitement aussi commun.
Bref, c\’est là qu\’intervient Linux et la puissance des outils qui lui sont associés. Dans un terminal :
$ sort -g mon_fichier | uniq > mon_nouveau_fichier
C\’est aussi simple que ça! Et le temps d\’exécution est très raisonnable :
$ time sort -g mon_fichier | uniq > mon_nouveau_fichier
real 0m8.013s
user 1m0.326s
sys 0m0.403s
Quelques brèves explications :
- sort -g permet le tri en prenant l\’ordre des valeurs numériques et pas l\’ordre alphanumérique classique. Sans cette option, on aurait un résultat de ce type : 1, 10, 100, 1000, 11, 110, 1110, …
- uniq permet de supprimer les doublons et de renvoyer les valeurs uniques.
Certes ce n\’est pas quelque chose dont on a besoin tous les jours mais ça permet de montrer encore une fois la diversité et la puissance des outils fournis sous Linux. Et ça encourage à chercher du côté de ces petits utilitaires avant de tenter des choses improbables ou de réinventer la roue…
EDIT : Il est aussi possible d\’effectuer le tout (tri + suppression des doublons) en ajoutant -u au sort. On aura donc sort -gu mon_fichier > mon_nouveau_fichier. Au niveau du temps d\’exécution il n\’y a aucune différence et le résultat est identique. Merci AP pour l\’info!
Le switch « -u » de sort permet d’éliminer les lignes en double pendant le tri et permet de se contenter d’un seul process au lieu de 2 process chaînés (avec l’économie de mémoire et de CPU que cela peut induire). Il ne permet toutefois pas toutes les subtilités offertes par la commande « uniq » mais si cette dernière est utilisée sans paramètres additionnels, on pourrait refaire un chronométrage :
time sort -gu ntest > uniq_sorted_test
Ah… j’avais pas vu ça. Je teste de suite et je met à jour mon post en fonction! Merci bien 😉
C’est assez curieux en fait puisque les temps d’exécution sont sensiblement les mêmes
Et la sortie est identique. Mais bon, c’est vrai qu’en une seule commande c’est peut-être mieux… Disons que ça permet de découvrir aussi uniq 😉
Ah ben on a été plus rapide que moi avec le « sort -gu » qui marche super bien
@Guiona : Une heure de retard pour le coup 😉 J’ai ajouté un « EDIT » à la fin de mon post à ce sujet.