<Précédent | Table des matières | Suivant>
sort
La sort programme trie le contenu de l'entrée standard, ou un ou plusieurs fichiers spécifiés sur la ligne de commande, et envoie les résultats à la sortie standard. En utilisant la même technique que nous avons utilisée avec cat, nous pouvons démontrer le traitement de l'entrée standard directement à partir du clavier :
[moi@linuxbox ~]$ trier > foo.txt
cba
[moi@linuxbox ~]$ chat foo.txt
a B C
[moi@linuxbox ~]$ trier > foo.txt
cba
[moi@linuxbox ~]$ chat foo.txt
a B C
Après avoir entré la commande, nous tapons les lettres "c", "b" et "a", suivies à nouveau par Ctrl-d pour indiquer la fin du fichier. Nous visualisons ensuite le fichier résultant et voyons que les lignes apparaissent maintenant dans l'ordre trié.
Depuis que sort peut accepter plusieurs fichiers sur la ligne de commande comme arguments, il est possible de fusionner plusieurs fichiers en un seul ensemble trié. Par exemple, si nous avions trois fichiers texte et que nous voulions les combiner en un seul fichier trié, nous pourrions faire quelque chose comme ceci :
trier fichier1.txt fichier2.txt fichier3.txt > final_sorted_list.txt
trier fichier1.txt fichier2.txt fichier3.txt > final_sorted_list.txt
sort a plusieurs options intéressantes. Voici une liste partielle:
Tableau 20-1 : Options de tri courantes
Option | Option longue | Description |
-b | --ignore-leader-blanks | Par défaut, le tri est effectué sur |
toute la ligne, en commençant par le | ||
premier caractère de la ligne. Cette | ||
l'option fait que le tri est ignoré | ||
les premiers espaces dans les lignes et | ||
calcule le tri en fonction du premier | ||
caractère non blanc sur le | ||
ligne. | ||
-f | --ignore-cas | Rend le tri insensible à la casse. |
-n | --tri numérique | Effectue un tri basé sur l'évaluation numérique d'une chaîne. L'utilisation de cette option permet d'effectuer le tri sur des valeurs numériques plutôt que sur des valeurs alphabétiques. |
-r | --sens inverse | Trier dans l'ordre inverse. Les résultats sont en |
descendant plutôt que ascendant | ||
ordre. | ||
-k | --clé=field1[,field2] | Trier en fonction d'un champ clé situé |
De field1 à field2 plutôt que le | ||
ligne entière. Voir la discussion ci-dessous. | ||
-m | --fusionner | Traiter chaque argument comme le nom |
d'un fichier pré-trié. Fusionner plusieurs | ||
fichiers en un seul résultat trié | ||
sans effectuer aucune autre | ||
tri. | ||
-o | --sortie=filet | Envoyer la sortie triée à filet plutôt |
que la sortie standard. | ||
-t | --field-séparateur=carboniser | Définir le séparateur de champ |
personnage. Par défaut les champs sont | ||
séparés par des espaces ou des tabulations. |
Bien que la plupart des options ci-dessus soient assez explicites, certaines ne le sont pas. Regardons d'abord le -n option, utilisée pour le tri numérique. Avec cette option, il est possible de trier les valeurs en fonction de valeurs numériques. Nous pouvons le démontrer en triant les résultats de la du commande pour déterminer les plus grands utilisateurs d'espace disque. Normalement, le du La commande répertorie les résultats d'un résumé dans l'ordre des chemins :
[moi@linuxbox ~]$ du -s /usr/share/* | diriger
252 /usr/share/aclocal
96 /usr/share/acpi-support
8 /usr/share/adduser
196 /usr/share/alacarte
344 /usr/share/alsa
8 /usr/share/alsa-base 12488 /usr/share/anthy
8 /usr/share/apmd
21440 /usr/share/app-install
48 /usr/share/application-registre
[moi@linuxbox ~]$ du -s /usr/share/* | diriger
252 /usr/share/aclocal
96 /usr/share/acpi-support
8 /usr/share/adduser
196 /usr/share/alacarte
344 /usr/share/alsa
8 /usr/share/alsa-base 12488 /usr/share/anthy
8 /usr/share/apmd
21440 /usr/share/app-install
48 /usr/share/application-registre
Dans cet exemple, nous transférons les résultats dans front limiter les résultats aux dix premières lignes. Nous pouvons produire une liste triée numériquement pour montrer les dix plus gros consommateurs d'espace de cette façon :
[moi@linuxbox ~]$ du -s /usr/share/* | trier -nr | diriger
509940 /usr/share/locale-langpack
242660 /usr/share/doc
197560 /usr/share/polices
179144 /usr/partage/gnome
146764 /usr/share/monspell
144304 /usr/share/gimp
135880 /usr/partage/dict
76508 /usr/share/icônes
68072 /usr/share/applications
62844 /usr/share/foomatic
[moi@linuxbox ~]$ du -s /usr/share/* | trier -nr | diriger
509940 /usr/share/locale-langpack
242660 /usr/share/doc
197560 /usr/share/polices
179144 /usr/partage/gnome
146764 /usr/share/monspell
144304 /usr/share/gimp
135880 /usr/partage/dict
76508 /usr/share/icônes
68072 /usr/share/applications
62844 /usr/share/foomatic
En utilisant le -n° options, nous produisons un tri numérique inversé, les valeurs les plus élevées apparaissant en premier dans les résultats. Ce tri fonctionne car les valeurs numériques apparaissent au début de chaque ligne. Mais que se passe-t-il si nous voulons trier une liste en fonction d'une valeur trouvée dans la ligne ? Par exemple, les résultats d'une ls -l:
[moi@linuxbox ~]$ ls -l /usr/bin | diriger
Total des 152948
-rwxr-xr-x | 1 | racine | racine | 34824 | 2016-04-04 | 02:42 | [ |
-rwxr-xr-x | 1 | racine | racine | 101556 | 2007-11-27 | 06:08 | a2p |
-rwxr-xr-x | 1 | racine | racine | 13036 | 2016-02-27 | 08:22 | une connexion |
-rwxr-xr-x | 1 | racine | racine | 10552 | 2007-08-15 | 10:34 | acpi |
-rwxr-xr-x | 1 | racine | racine | 3800 | 2016-04-14 | 03:51 | acpi_fakekey |
-rwxr-xr-x | 1 | racine | racine | 7536 | 2016-04-19 | 00:19 | acpi_écouter |
-rwxr-xr-x | 1 | racine | racine | 3576 | 2016-04-29 | 07:57 | ajouter une partie |
-rwxr-xr-x | 1 | racine | racine | 20808 | 2016-01-03 | 18:02 | addr2ligne |
-rwxr-xr-x | 1 | racine | racine | 489704 | 2016-10-09 | 17:02 | adepte_batch |
Ignorant, pour le moment, que ls peut trier ses résultats par taille, nous pourrions utiliser sort pour trier également cette liste par taille de fichier :
[moi@linuxbox ~]$ ls -l /usr/bin | trier -nr -k 5 | diriger
-rwxr-xr-x | 1 | racine | racine | 8234216 | 2016-04-07 | 17:42 | Inkscape |
-rwxr-xr-x | 1 | racine | racine | 8222692 | 2016-04-07 | 17:42 | vue d'encre |
-rwxr-xr-x | 1 | racine | racine | 3746508 | 2016-03-07 | 23:45 | guimp-2.4 |
-rwxr-xr-x | 1 | racine | racine | 3654020 | 2016-08-26 | 16:16 | combien |
-rwxr-xr-x | 1 | racine | racine | 2928760 | 2016-09-10 | 14:31 | gdbtui |
-rwxr-xr-x | 1 | racine | racine | 2928756 | 2016-09-10 | 14:31 | gdb |
-rwxr-xr-x | 1 | racine | racine | 2602236 | 2016-10-10 | 12:56 | net |
-rwxr-xr-x | 1 | racine | racine | 2304684 | 2016-10-10 | 12:56 | client rpc |
-rwxr-xr-x | 1 | racine | racine | 2241832 | 2016-04-04 | 05:56 | aptitude |
-rwxr-xr-x | 1 | racine | racine | 2202476 | 2016-10-10 | 12:56 | smbcacls |
De nombreuses utilisations de sort impliquent le traitement de données tabulaires, comme les résultats de la ls commande ci-dessus. Si nous appliquons la terminologie de base de données au tableau ci-dessus, nous dirions que chaque ligne est un record et que chaque enregistrement se compose de plusieurs des champs, tels que les attributs de fichier, le nombre de liens, le nom de fichier, la taille du fichier, etc. sort est capable de traiter des champs individuels. En termes de base de données, nous sommes en mesure de spécifier un ou plusieurs champs clés à utiliser comme clés de tri. Dans l'exemple ci-dessus, nous spécifions le n et de r options pour effectuer un tri numérique inversé et spécifier -k 5 faire sort utilisez le cinquième champ comme clé de tri.
La k option est très intéressante et possède de nombreuses fonctionnalités, mais nous devons d'abord parler de la façon dont sort définit les champs. Considérons un fichier texte très simple constitué d'une seule ligne contenant le nom de l'auteur :
William Shotts
William Shotts
Par défaut, sort considère cette ligne comme ayant deux champs. Le premier champ contient les caractères :
"William"
et le deuxième champ contient les caractères :
« Shots »
ce qui signifie que les caractères d'espacement (espaces et tabulations) sont utilisés comme délimiteurs entre les champs et que les délimiteurs sont inclus dans le champ lors du tri.
En regardant à nouveau une ligne de notre ls sortie, nous pouvons voir qu'une ligne contient huit champs et que le cinquième champ est la taille du fichier :
-rwxr-xr-x 1 racine racine 8234216 2016-04-07 17:42 inkscape
-rwxr-xr-x 1 racine racine 8234216 2016-04-07 17:42 inkscape
Pour notre prochaine série d'expériences, considérons le fichier suivant contenant l'historique de trois distributions Linux populaires publiées de 2006 à 2008. Chaque ligne du fichier comporte trois champs : le nom de la distribution, le numéro de version et la date de sortie en MM/JJ Format /AAAA :
SUSE | 10.2 | 12/07/2006 |
Fedora | 10 | 11/25/2008 |
SUSE | 11.0 | 06/19/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
SUSE | 10.3 | 10/04/2007 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.10 | 10/18/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 6 | 10/24/2006 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 6.06 | 06/01/2006 |
Ubuntu | 8.10 | 10/30/2008 |
Fedora | 5 | 03/20/2006 |
Utiliser un éditeur de texte (peut-être entrain), nous allons saisir ces données et nommer le fichier résultant distributions.txt.
Ensuite, nous allons essayer de trier le fichier et observer les résultats :
[moi@linuxbox | ~]$ | trier les distributions.txt |
Fedora 10 | 11/25/2008 | |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
SUSE10.1 | 05/11/2006 | |
SUSE10.2 | 12/07/2006 | |
SUSE10.3 | 10/04/2007 | |
SUSE11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Eh bien, cela a surtout fonctionné. Le problème se produit dans le tri des numéros de version de Fedora. Étant donné qu'un « 1 » précède un « 5 » dans le jeu de caractères, la version « 10 » se termine en haut tandis que la version « 9 » tombe en bas.
Pour résoudre ce problème, nous allons devoir trier sur plusieurs clés. Nous souhaitons effectuer un tri alphabétique sur le premier champ puis un tri numérique sur le deuxième champ. sort permet
plusieurs instances de la -k option afin que plusieurs clés de tri puissent être spécifiées. En fait, une clé peut inclure une série de champs. Si aucune plage n'est précisée (comme cela a été le cas avec nos exemples précédents), sort utilise une clé qui commence par le champ spécifié et s'étend jusqu'à la fin de la ligne. Voici la syntaxe de notre tri multi-clés :
[moi@linuxbox | ~]$ | trier --key=1,1 --key=2n distributions.txt |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
Fedora 10 | 11/25/2008 | |
SUSE10.1 | 05/11/2006 | |
SUSE10.2 | 12/07/2006 | |
SUSE10.3 | 10/04/2007 | |
SUSE11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Bien que nous ayons utilisé la forme longue de l'option pour plus de clarté, -k 1,1 -k 2n serait exactement équivalent. Dans la première instance de l'option clé, nous avons spécifié une plage de champs à inclure dans la première clé. Comme nous voulions limiter le tri au premier champ, nous avons spécifié 1,1 ce qui signifie « commencer au premier champ et terminer au premier champ ». Dans le second cas, nous avons spécifié 2n, ce qui signifie que le champ 2 est la clé de tri et que le tri doit être numérique. Une lettre d'option peut être incluse à la fin d'un spécificateur de clé pour indiquer le type de tri à effectuer. Ces lettres d'option sont les mêmes que les options globales pour le sort programme : b (ignorer les blancs de début), n (tri numérique), r (tri inversé), et ainsi de suite.
Le troisième champ de notre liste contient une date dans un format peu pratique pour le tri. Sur les ordinateurs, les dates sont généralement formatées dans l'ordre AAAA-MM-JJ pour faciliter le tri chronologique, mais les nôtres sont au format américain MM/JJ/AAAA. Comment peut-on trier cette liste par ordre chronologique ?
Heureusement, sort fournit un moyen. L'option clé permet de spécifier compensations dans les champs, nous pouvons donc définir des clés dans les champs :
[moi@linuxbox ~]$ trier -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11/25/2008
Ubuntu 8.10 10/30/2008
[moi@linuxbox ~]$ trier -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11/25/2008
Ubuntu 8.10 10/30/2008
SUSE | 11.0 | 06/19/2008 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
Ubuntu | 7.10 | 10/18/2007 |
SUSE | 10.3 | 10/04/2007 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.2 | 12/07/2006 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 6 | 10/24/2006 |
Ubuntu | 6.06 | 06/01/2006 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 5 | 03/20/2006 |
En précisant -k 3.7 nous instruisons sort d'utiliser une clé de tri qui commence au septième caractère du troisième champ, qui correspond au début de l'année. De même, nous précisons -k 3.1 et de -k 3.4 pour isoler les parties mois et jour de la date. Nous ajoutons également le n et de r options pour obtenir un tri numérique inversé. Les b Une option est incluse pour supprimer les espaces de début (dont les numéros varient d'une ligne à l'autre, affectant ainsi le résultat du tri) dans le champ de date.
Certains fichiers n'utilisent pas de tabulations et d'espaces comme délimiteurs de champs ; par exemple, le / Etc / passwd
fichier:
[moi@linuxbox ~]$ tête /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
[moi@linuxbox ~]$ tête /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
Les champs de ce fichier sont délimités par des deux-points (:), alors comment trierions-nous ce fichier à l'aide d'un champ clé ? sort Fournit le -t option pour définir le caractère séparateur de champ. Pour trier les passwd fichier sur le septième champ (le shell par défaut du compte), nous pourrions faire ceci :
[moi@linuxbox ~]$ sort -t ':' -k 7 /etc/passwd | diriger
moi:x:1001:1001:Moi,,,:/home/me:/bin/bash
[moi@linuxbox ~]$ sort -t ':' -k 7 /etc/passwd | diriger
moi:x:1001:1001:Moi,,,:/home/me:/bin/bash
root:x:0:0:root:/root:/bin/bash dhcp:x:101:102::/nonexistant:/bin/false
gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false hplip:x:104:7:HPLIP system user,,,:/var/run/hplip:/bin/false klog :x:103:104::/home/klog:/bin/false messagebus:x:108:119::/var/run/dbus:/bin/false polkituser:x:110:122:PolicyKit,,,: /var/run/PolicyKit:/bin/false pulse:x:107:116:PulseAudio daemon,,,:/var/run/pulse:/bin/false
root:x:0:0:root:/root:/bin/bash dhcp:x:101:102::/nonexistant:/bin/false
gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false hplip:x:104:7:HPLIP system user,,,:/var/run/hplip:/bin/false klog :x:103:104::/home/klog:/bin/false messagebus:x:108:119::/var/run/dbus:/bin/false polkituser:x:110:122:PolicyKit,,,: /var/run/PolicyKit:/bin/false pulse:x:107:116:PulseAudio daemon,,,:/var/run/pulse:/bin/false
En spécifiant le caractère deux-points comme séparateur de champ, nous pouvons trier sur le septième champ.