Comment trier la chaîne qui s'est combinée avec chaîne + numérique en utilisant le script bash?


27

Ce sont les données que je veux trier. Mais sorttraite le numérique en chaîne, les données ne sont pas triées comme je m'y attendais.

/ home / fichiers / profile1
/ home / files / profile10
/ home / files / profile11
/ home / files / profile12
/ home / files / profile14
/ home / files / profile15
/ home / files / profile16
/ home / files / profile2
/ home / files / profile3
/ home / files / profile4
/ home / files / profile5
/ home / files / profile6
/ home / files / profile7
/ home / files / profile8
/ home / files / profile9

Je veux trier ça pour,

/ home / fichiers / profile1
/ home / fichiers / profile2
/ home / fichiers / profile3
/ home / files / profile4
/ home / files / profile5
/ home / files / profile6
/ home / files / profile7
/ home / files / profile8
/ home / files / profile9
/ home / files / profile10
/ home / files / profile11
/ home / files / profile12
/ home / files / profile14
/ home / files / profile15
/ home / files / profile16

Existe-t-il un bon moyen par script bash? Je ne peux pas utiliser de script ruby ​​ou python ici.


essayez d'utiliser "sort -nd"
bobah

1
@bobah, "trier: les options` -dn 'sont incompatibles "
maxschlepzig

10
sort -Vferait.
Thor

2
@Thor. votre commentaire ferait une bonne réponse
Peter.O

Réponses:


21

Vous pouvez utiliser un caractère sentinelle temporaire pour délimiter le nombre:

$ sed 's/\([0-9]\)/;\1/' log | sort -n -t\; -k2,2 | tr -d ';'

Ici, le caractère sentinelle est ';' - il ne doit faire partie d'aucun nom de fichier que vous souhaitez trier - mais vous pouvez échanger le ';' avec n'importe quel personnage que vous aimez. Vous devez modifier le sed, sortpuis trséparer en conséquence.

Le canal fonctionne comme suit: La sedcommande insère la sentinelle avant tout nombre, la sortcommande interprète la sentinelle comme délimiteur de champ, trie avec le deuxième champ comme clé de tri numérique et la trcommande supprime à nouveau la sentinelle.

Et logdénote le fichier d'entrée - vous pouvez également diriger votre entrée dans sed.


J'aime la façon dont vous avez résolu le problème :)
SHW

44

C'est très similaire à cette question . Le problème est que vous avez un champ alphanumérique que vous -ntriez et ne le traite pas de manière sensible, contrairement à la version sort ( -V). Utilisez donc:

sort -V

Notez que cette fonctionnalité est actuellement prise en charge par les implémentations de tri GNU, FreeBSD et OpenBSD.


Savez-vous à quel point c'est portable? Cette option ne semble pas faire partie de la spécification POSIX.
Ernest A

@ErnestA: Vous avez raison, il s'agit d'une solution spécifique au tri GNU. Ajout d'une note.
Thor

@ErnestA: J'ai l'impression que FreeBSD et OpenBSD ont ajouté cette fonctionnalité.
Thor

Et cela ne fonctionne pas si les numéros ont des préfixes différents.
Dante

1
Pour tous les lecteurs: Notez qu'il s'agit d'un CAPITAL V! N'utilisez sort -Vpas sort -v. C'est difficile à dire à première vue.
Gabriel Staples

7

Si tous vos noms de fichiers ont le même préfixe avant la dernière partie numérique, ignorez-le lors du tri:

sort -k 1.20n

(20 est la position du premier chiffre. C'est un plus la longueur de /home/files/profile.)

Si vous avez plusieurs parties non numériques différentes, insérez une sentinelle .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.