Trier par le dernier caractère de l'input, puis par le numéro précédent?

J'ai un file qui ressemble à ceci:

foo03a foo02b quux01a foo01a foo02a foo01b foo03b quux01b 

Je voudrais qu'il soit ordonné par le dernier caractère (donc a et b apparaissent set) puis par le numéro précédent, puis par le préfixe (bien que cela ne soit pas essentiel). Pour qu'il en résulte:

 foo01a quux01a foo02a foo03a foo01b quux01b foo02b foo03b 

En fait, peu importe où quux01a et quux01b apparaissent, tant qu'ils sont dans le groupe concerné – ils peuvent apparaître comme indiqué, avant foo01b , ou après foo03b .

Pourquoi? Ce sont des noms de servers utilisés dans un deployment bleu / vert, donc je veux les servers 'A' set, puis les servers 'B'.

J'ai trouvé le -k switch à GNU sort, mais je ne comprends pas comment l'utiliser pour spécifier un caractère particulier, en comptant à partir de la fin de la string.

J'ai essayé cat foos | rev | sort | rev cat foos | rev | sort | rev cat foos | rev | sort | rev , mais qui sortinge foo10a et foo10b (quand on count jusque là) au mauvais endroit.

J'ai trouvé une solution en utilisant la fonction de match GNU awk :

 cat foos | \ gawk 'match($0, /([^0-9]+)([0-9]+)([^0-9]+)/, a) {print a[3], a[2], $0}' | \ sort | cut -d' ' -f3 

La command gawk utilise des captures regex pour générer la key de sorting, de sorte que je me retrouve avec les éléments suivants:

 a 03 foo03a b 02 foo02b 

…etc.

Exécute ça à travers, cut pour les champs que je veux. Terminé.

Vous pouvez sort par la position du caractère (indiqué par le nombre après . ) Du champ (ici le champ 1):

 sort -k1.6 -k1.4,1.5n -k1.1,1.3 file.txt 

Exemple:

 $ cat file.txt foo03a foo02b foo01a foo02a foo01b foo03b $ sort -k1.6 -k1.4,1.5n -k1.1,1.3 file.txt foo01a foo02a foo03a foo01b foo02b foo03b 

Façon inverse, en utilisant rev :

 $ rev file.txt | sort -k1.1,1.1 -k1.2,1.3n -k1.4 | rev foo01a foo02a foo03a foo01b foo02b foo03b