i've attached a little program that extends
seq to print sequences in hex or octal. for example,
; seq.rc -f %.4x 0x3b1 0x3b2
03b1
03b2
i did it in rc (really awk) because it was too tedious
to get the details right in c.
as such, formats are as in printf(2) not as in print(2).
this is a bug, but i don't see a reasonable workaround.
even using awk and adding functionality, the new
program is *way* faster than seq:
; >/dev/null time seq 1 100000
1.90u 0.09s 1.99r seq 1 100000
; >/dev/null time seq.rc 1 100000
0.28u 0.00s 0.29r seq.rc 1 100000
- erik
#!/bin/rc
awk '
function hex(s, base, r, n, i, k, c)
{
base = 16;
if(s ~ /^0[xX][0-9a-fA-F]+/)
s = substr(str, 3);
n = length(s)
r = 0
for (i = 1; i <= n; i++) {
c = tolower(substr(s, i, 1))
k = index("0123456789abcdef", c) - 1;
r = r * base + k
}
return r
}
function mystrtonum(str0, neg, base, str, r, n, i, k, c)
{
base = 0;
neg = 0;
str = str0;
if(str ~ /^\+/)
str = substr(str, 2)
if(str ~ /^-/){
str = substr(str, 2)
neg = 1
}
if(str ~ /^0[0-7]*$/)
base = 8
if(str ~ /^0[xX][0-9a-fA-F]+/){
str = substr(str, 3);
base = 16;
}
if(base != 0){
n = length(str)
r = 0
for (i = 1; i <= n; i++) {
c = tolower(substr(str, i, 1))
k = index("0123456789abcdef", c) - 1;
r = r * base + k
}
}else if(str ~ /^[0-9]*([.][0-9]*)?([Ee][-+]?[0-9]+)?$/)
r = str0 + 0
else
r = "NaN"
return r
}
function usage()
{
print "usage: seq [-w] [-f fmt] min [inc] max" > "/fd/2"
exit(1);
}
function EARGF()
{
if(j + 1 < length(a))
return substr(a, j+1, 100);
i++;
if(i >= ARGC)
usage();
return ARGV[i];
}
function args()
{
for(i = 1; i < ARGC; i++){
a = ARGV[i]
if(a !~ /^-..*/)
break;
for(j = 2; j <= length(a); j++){
c = substr(a, j, 1);
if(c == "w")
flagw = 1
else if(c == "f"){
format = EARGF()
if(format !~ /\n$/)
format = format "\n"
}else
usage()
}
}
n = ARGC - i
if(n != 2 && n != 3)
usage()
min = mystrtonum(ARGV[i++])
incr = 1
if(n == 3)
incr = mystrtonum(ARGV[i++])
max = mystrtonum(ARGV[i++])
}
function buildfmt()
{
if(length(format) > 0)
return;
format = "%g\n";
if(!flagw)
return;
maxw = 0;
maxp = 0;
for(val = min; val <= max; val += incr){
buf = sprintf("%g", val)
if(buf ~ /e/)
return
parts = split(buf, ary, "\.");
w = length(ary[1]);
p = length(ary[2]) + parts==2;
if(w>maxw)
maxw = w;
if(p>maxp)
maxp = p;
}
if(maxp > 0)
maxw += maxp+1;
format = sprintf("%%0%d.%df\n", maxw, maxp);
}
BEGIN{
args();
buildfmt()
for(val = min;; val += incr){
if(incr > 0 && val > max)
break;
if(incr < 0 && val < max)
break;
printf(format, val)
}
exit(0);
}' $*