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.

user760548
la source
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
stackoverflow.com/questions/13088370/sort-numerically
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

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.

maxschlepzig
la source
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.

Thor
la source
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 .

Gilles 'SO- arrête d'être méchant'
la source