Utilisation de coreutils sort , comment puis-je trier numériquement par une valeur hexadécimale (champ) ? Je m'attendais à quelque chose du genre
sort -k3,3x file_to_sort
cependant, un tel x n'existe pas.
Edit :La meilleure solution que j'ai trouvée jusqu'à présent est :
{ echo ibase=16; cut -d' ' -f3 file_to_sort; } |
bc | paste -d: - file_to_sort | sort -t: -k1,1n | cut -d: -f2-
où le cut -d' ' -f3 isole le champ de recherche (il s'agit de -k3,3 — cela peut varier, bien sûr), et bc effectue la conversion en décimal (nécessite un hexadécimal majuscule, sans 0x préfixe, correspondant à mon cas). Ensuite, je joins, trie et divise les colonnes.
Entrée d'échantillon minimale :
5 hhf 25
3 ezh ae
1 hdh d12
2 ukr 9f
4 jjk 7
Sortie attendue (fichier trié par hex troisième colonne):
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Réponse acceptée :
Une solution en perl :
$ perl -anle '
push @h, [$F[-1],$_];
END {
print for map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_->[1],hex($_->[0])] } @h;
}
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Explication
-
Lors du traitement du fichier, nous créons un tableau de tableau
@h, chacun de ses éléments est une référence de tableau[$F[-1],$_], avec le premier élément est la valeur hexadécimale à comparer, et le deuxième élément est la ligne entière. -
Dans
ENDbloc, nous utilisons la transformée de Schwartz :-
Avec chaque élément de
@h, crée un tableau anonyme, contient toute la ligne ($_->[1]le deuxième élément de chaque ref de tableau dans@h) et la valeur hexadécimale à comparerhex($_->[0])] -
Trier au-dessus de la base du tableau sur la valeur hexadécimale
$a->[1] <=> $b->[1] -
Récupère le premier élément de chaque référence de tableau dans le tableau trié
map { $_->[0] }puis imprimez le résultat.
-
Mettre à jour
Avec la suggestion de @Joseph R, sans utiliser la transformation de Schwartz :
$ perl -anle '
push @h, [hex($F[-1]),$_];
END {
print $_->[1] for
sort { $a->[0] <=> $b->[0] } @h;
}
' file
Mise à jour 2
Après avoir lu le commentaire de Stefan, je pense que cela peut appeler direct :
$ perl -e '
print sort {hex((split(/s+/,$a))[-1]) <=> hex((split(/s+/,$b))[-1])} <>;
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12