17

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? 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
    Feb 23, 2017 at 10:14
  • Ok. Then you could set OFMT. Or use printf() instead of print. 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/… Jun 5, 2018 at 21:18

5 Answers 5

40

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
1
  • 3
    example to convert the first column from stdout : echo -e "1024 1048576\n1048576 1024 " | numfmt --to iec
    – Indent
    Dec 8, 2020 at 16:56
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
    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. 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.