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
END
bloc, 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