Hello Everybody !!!. i have question in mind, is it possible to sort a list of hexadecimal numbers using "sort" command?
From the book "UNIX power tools By Shelley Powers, Jerry Peek"
There is no provision for sorting hexadecimal numbers
In this way we can sort
$ cat hexanumbers.txt
3E80
3EF8
460
$ cat testfile.sh
#!/bin/ksh
for i in `cat hexanumbers.txt | awk '{ print "16#"$0}'`
do
typeset -i10 i
echo $i >> decimals_list.txt
done
for i in `cat decimals_list.txt | sort`
do
echo "obase=16;$i" | bc
done
rm decimals_list.txt
$ ksh testfile.sh
460
3E80
3EF8
$
Hi.
The utility msort might be found in your repository, or, failing that, at MSORT
Best wishes ... cheers, drl
based on jayan_jay's, here's a bash script :
$ cat hexanumbers.txt
3E80
3EF8
460
$ while read hexnum; do array[16#$hexnum]="$hexnum"; done < hexanumbers.txt
$ printf '%s\n' "${array[@]}"
460
3E80
3EF8
awk '{printf("%050s\t%s\n", toupper($0), $0)}' hex-data | LC_COLLATE=C sort -k1,1 | cut -f2
If you take a look at the C/POSIX collation sequence, you'll see that the sequences A-F and a-f both sort after 0-9 in the POSIX/C locale. So long as the hex numbers do not mix case and are of the same length, the string collation sequence is congruent to a hex digits sequence.
LC_COLLATE Category in the POSIX Locale
If you have a list of hex numbers, you can decorate them with a column of zero-padded, case-folded numbers, sort on that column, then output the original numbers.
$ cat hex-data
3e80
3EF8
460
$ awk '{printf("%050s\t%s\n", toupper($0), $0)}' hex-data | LC_COLLATE=C sort -k1,1 | cut -f2
460
3e80
3EF8
Regards,
Alister
IMO, if the OP really have such numbers he should just normalize them. And there is no need to undecorate them back.
cat NUMS | xargs printf "%4s\n" | tr 'a-z ' 'A-Z0' | sort
(It is "useful use" of cat).
Or with awk if there are several numbers on lines:
awk '{
for ( i = 1; i <= NF; i++ ) {
s = sprintf("%04s", $i)
gsub(" ", "0", s)
printf s " "
}
print ""
}' NUMS | tr a-z A-Z | sort
Use 2 or 8 for bytes and 32-bit words.
Here's how it can be done with perl...
perl -e '@a=(0x3E80,0x3EF8,0x460);@r=sort {$a <=> $b} @a;printf("%X\n" x @r,@r);'
Thanks Drl i will give it a shot.......:)
Hi.
In some situations, a string representing a hex number may need an adjustment to be recognized, such as adding a prefix "0x" -- that's what you would need to do with msort to get it to recognize hex numbers. If one has a file of "plain" hex numbers, then one solution to use the standard sort might be to do such an adjustment if necessary, add a column to the line in decimal, then sort that intermediate file, and finally eliminate the first column, say with cut.
Here's is a longish script that uses a perl script to do some of that work. The data file is a made-up report of manufacturers in countries that create widgets with a number of employees, all with fictitious hex numbers:
#!/usr/bin/env bash
# @(#) s4 Demonstrate sort of hex column.
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C perl sort cut
COL=${1-2}
FILE=data4
pl " Input data file $FILE (aligned):"
pe " Country widgets manufacturers employees"
pe
align $FILE
pl " Results, sorted on column $COL, aligned:"
./p1 $COL < $FILE |
tee f1 |
sort -k1,1n |
tee f2 |
cut -f2- |
tee f3 |
align
COL=4
pl " Results, sorted on column $COL, aligned:"
./p1 $COL < $FILE |
tee f1 |
sort -k1,1n |
tee f2 |
cut -f2- |
tee f3 |
align
pl " Addendum, perl script \"p1\" to add the decimal equivalent:"
cat p1
exit 0
producing:
% ./s4
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution : Debian GNU/Linux 5.0.8 (lenny)
GNU bash 3.2.39
perl 5.10.0
sort (GNU coreutils) 6.10
cut (GNU coreutils) 6.10
-----
Input data file data4 (aligned):
Country widgets manufacturers employees
Belarus f59 26 3a
Gibraltar b26 2b 25
Iceland aaf 23 2e
Ireland 426 29 29
Netherlands d4d 17 5a
Slovakia 91d 2c 42
Spain 556 31 2d
Switzerland 49a 2e 54
Turkey 9e5 15 46
Ukraine 1154 26 4a
-----
Results, sorted on column 2, aligned:
Ireland 426 29 29
Switzerland 49a 2e 54
Spain 556 31 2d
Slovakia 91d 2c 42
Turkey 9e5 15 46
Iceland aaf 23 2e
Gibraltar b26 2b 25
Netherlands d4d 17 5a
Belarus f59 26 3a
Ukraine 1154 26 4a
-----
Results, sorted on column 4, aligned:
Gibraltar b26 2b 25
Ireland 426 29 29
Spain 556 31 2d
Iceland aaf 23 2e
Belarus f59 26 3a
Slovakia 91d 2c 42
Turkey 9e5 15 46
Ukraine 1154 26 4a
Switzerland 49a 2e 54
Netherlands d4d 17 5a
-----
Addendum, perl script "p1" to add the decimal equivalent:
#!/usr/bin/env perl
# @(#) p1 Demonstrate extraction of hex column, convert to decimal.
use warnings;
use strict;
my ($debug);
$debug = 1;
$debug = 0;
# Select column (beginning from 0, allow user to specify from 1.
my ($col) = shift || "2";
# Set separator.
my ($sep) = "\t";
# Walk through file.
while (<>) {
chomp;
my (@a) = split /$sep/;
my ($t1) = $a[ $col - 1 ];
print " hex column is $col, content before is :$t1:\n" if $debug;
$t1 =~ s/\s*//g;
print " hex column is $col, content after is :$t1:\n" if $debug;
print hex($t1), "$sep$_\n";
}
exit(0);
The shell script allows a column number to passed in to select the column to be sorted.
The files f1, f2, etc., allow the viewing of intermediate results; they can be eliminated for production use.
This also uses align so that the columns are readable, see Read an ascii as cell-tabulated form for more information about that ... cheers, drl