0

I have one file which produces the output shown below. How can I convert 100571394 bytes in GB using Bash? Is there any script for that?

 2018-02-01 23:29:01 CET usr1@abc.com 100571394 bytes   
 2018-02-01 23:29:58 CET usr2@abc.com 35196735 bytes   
 2018-02-01 23:30:56 CET usr3@abc.com 1187519 bytes  
 2018-02-01 23:34:01 CET usr4@abc.com 121153336 bytes  
 2018-02-01 23:37:13 CET usr5@abc.com 57589006 bytes
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Possible duplicate of [Convert number to human-readable KB/MB/GB/TB](https://stackoverflow.com/questions/36722572/convert-number-to-human-readable-kb-mb-gb-tb) – Benjamin W. Feb 03 '18 at 20:14
  • Do you want gigabytes (GB or 10⁹) or gibibytes (GiB or 2³⁰)? The difference in size is 7.37%. Dealing with gigabytes is an editing problem (add a decimal point before the 9th digit from the right) whereas gibibytes requires computation too. How many fractional digits do you want? Trailing zeros? How big can the values be? Presumably, not much more than petabytes (PB) or pebibytes (PiB), so 64-bit integer arithmetic is sufficient for the raw values, but you need floating point arithmetic (which Bash does _not_ provide, unlike the Korn shell). The `expr` command only does integers — use `bc`. – Jonathan Leffler Feb 03 '18 at 23:22
  • What is the expected output for `usr3@abc.com` — in fact, for each line shown since none of the values is more than about 1/10 of a gigabyte? You should probably use `example.com` in place of `abc.com` — the `example.com` domain is reserved for such uses, but `abc.com` is a news/media company. – Jonathan Leffler Feb 03 '18 at 23:24

1 Answers1

0

This is little script I use. It may not be correct but it's what I use. YMMV

awk '{ split( "B KiB MiB GiB TiB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } print int($1) v[s] }'

For example:

echo 100571394 |
awk '{ split( "B KiB MiB GiB TiB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } print int($1) v[s] }'
95GiB

For your file you could run it through a while loop:

while IFS= read -r line; do 
    echo "$line" |
    awk '{print $5}' |
    awk '{ split( "B KiB MiB GiB TiB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } print int($1) v[s] }'
done < Your_example_file
95MiB
33MiB
1MiB
115MiB
54MiB
  • By my reckoning, 100571394 bytes is approximately 100 MiB or 0.1 GiB. I think you have a your sizes out by a factor of 1024 (you've forgotten to allow for simple bytes — less than 1 KiB). You can demonstrate by using `echo 1` piped to your script; it reports 1 KiB; for `echo 10` it reports `10 KiB`, so it isn't simply rounding up. The fix is easy: add `B` and a space before `KiB`. – Jonathan Leffler Feb 04 '18 at 04:01
  • Thanks for pointing that out. I suppose I only used this for really big numbers and this script just made them even bigger! Thanks for the solution as well! – John Mehorter Feb 05 '18 at 10:38