# Convert numbers to SI notation

\$ awk '{ split(sprintf("%1.3e", \$1), b, "e"); p = substr("yzafpnum_kMGTPEZY", (b[2]/3)+9, 1); o = sprintf("%f", b[1] * (10 ^ (b[2]%3))); gsub(/\./, p, o); print substr( gensub(/_[[:digit:]]*/, "", "g", o), 1, 4); }' < test.dat
converts any number on the 'stdin' to SI notation. My version limits to 3 digits of precious (working with 10% resistors).
Sample Output
```1
10
100
1k23
10k0
100k
1M00
24k5
4k54
2P35
0m34
0n35```

2
2009-07-22 16:54:14

### What Others Think

awk.exe?
RickDeckardt · 705 weeks and 2 days ago
More readable version (with biasing for m,u,n,..) -- { split(sprintf("%1.3e", \$1), bits, "e"); if (bits[2] < 0) { bits[1] *= 1000; bits[2] -= 3; } prefix = substr("yzafpnum_kMGTPEZY", (bits[2]/3)+9, 1) output = sprintf("%f", bits[1] * (10 ^ (bits[2]%3))); gsub(/\./, prefix, output); print substr( gensub(/_[[:digit:]]*/, "", "g", output), 1, 4); } --
mungewell · 705 weeks and 2 days ago
yeah yeah cygwin you know... ;-)
mungewell · 705 weeks and 2 days ago
There has GOT to be a better way to do this
linuxrawkstar · 705 weeks and 2 days ago
I wish I could find a better way, spent about an hour googling. Better version: -- { split(sprintf("%-1.2e", \$1), bits, "e"); prefix = substr("yzafpnum.kMGTPEZY", (bits[2]/3)+9, 1) output = sprintf("%f", bits[1] * (10 ^ ((bits[2]+18)%3))); gsub(/\./, prefix, output); print gensub(/\.\$/, "", "g", gensub(/[0]*\$/, "", "g", output)); } --
mungewell · 705 weeks and 2 days ago
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .