27

I have the given code below for converting bytes to the corresponding values:

for OUTPUT in $(find $IP_DIR -maxdepth 1 | awk 'NR>1')
do
    case $RETURNSIZE in
        "gb") FS=`du -b $OUTPUT | awk {'print $1'}`
              FS=`echo $FS | awk '{ byte =$1 /1024/1024**2 ; print byte " GB" }'`
              echo $OUTPUT "|" $FS;;
        "mb") FS=`du -b $OUTPUT | awk {'print $1'}`
              FS=`echo $FS | awk '{ byte =$1 /1024/1024 ; print byte " MB" }'`
              echo $OUTPUT "|" $FS;;
        "kb") FS=`du -b $OUTPUT | awk {'print $1'}`
              FS=`echo $FS | awk '{ byte =$1 /1024 ; print byte " KB" }'`
              echo $OUTPUT "|" $FS;;
        "b")  FS=`du -b $OUTPUT | awk {'print $1'}`
              echo $OUTPUT "|" $FS "B";;
    esac
    

OUTPUT

/home/work/exten.sh | 3.53903e-07 GB
/home/work/e.txt | 0 GB
/home/work/t.txt | 0 GB
/home/worktest | 9.53674e-07 GB
/home/work/s.txt | 3.23169e-07 GB

The logic seems to be perfectly working but when the case comes to gb (RETURNSIZE), the result is in exponential format.

But I am looking for the result in normal decimal format.

4
  • 1
    Since you tagged your question with linux: what's wrong with du -Sh? Commented Feb 23, 2017 at 9:32
  • @SatoKatsura I cannot use that flag because my requirement is to get the output i.e. the size in actual figures. And "-h" flag gives me the values rounded off.
    – ramp
    Commented Feb 23, 2017 at 10:14
  • Ok. Then you could set OFMT. Or use printf() instead of print. Commented Feb 23, 2017 at 10:41
  • 1
    Note this GB calculation is the "Gigibyte" method (how system memory is calculated, all 1024's no 1000s). As such the "GB" above is the wrong label, and should be "GiB". See hexus.net/tech/tech-explained/storage/… Commented Jun 5, 2018 at 21:18

5 Answers 5

61

Since this is Linux I'm surprised no-one mentioned the numfmt command:

numfmt - Convert numbers from/to human-readable strings

>>numfmt --to iec --format "%8.4f" 599511627776
558.3388G
2
  • 3
    example to convert the first column from stdout : echo -e "1024 1048576\n1048576 1024 " | numfmt --to iec
    – Indent
    Commented Dec 8, 2020 at 16:56
  • 3
    This also works the other way around like numfmt --from=auto 10Gi which is useful for parsing user input.
    – piedar
    Commented Jan 14 at 16:09
8

I haven't tested, but I think it has something to do with you loading the bc mathlib with bc -l.

Try changing the awk calculation piece for GB to:

awk '{ byte =$1 /1024/1024/1024; print byte " GB" }'

Note: 1024/1024**2 is equivalent to 1024/1024/1024 in awk.

2
  • Sorry by mistake I had pasted the trail code there earlier. Now I have edited them. I have tried this possibility earlier itself. I was still getting the values in exponential form. Along with this "1 GB = 1073741824 B = 1048576 MB"
    – ramp
    Commented Feb 23, 2017 at 10:29
  • This is nice and neat. The "GB vs "GiB" comment I made in the accepted answer, also applies here. Commented Jun 5, 2018 at 21:19
3
> printf "1GiB\\nMB" | units
Currency exchange rates from finance.yahoo.com on 2017-10-31 
3047 units, 109 prefixes, 109 nonlinear units

You have: You want:     * 1073.7418
        / 0.00093132257
You have:

or

> echo $((1024*1024*1024))
1073741824
>   

See also: man 7 units

HTH

2

Why don't you use bc instead of awk? Like:

$ a=2342341234534634653453452342
$ echo "scale=2; $a/1024/1024" | bc -l
2233830675634989407971.81
0

Made a small cli for this.

https://github.com/gonejack/hsize

> hsize 123 45678
123 => 123B
45678 => 44.61KB
> echo 19129219219129119 | hsize
19129219219129119 => 16.99PB

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .