maaboo
maaboo

Reputation: 137

Convert number to gigabytes (sed, awk, sh, bash)

I have the following multi-line output:

Volume Name: GATE02-SYSTEM
Size: 151934468096
Volume Name: GATE02-S
Size: 2000112582656

Is it possible to convert strings like:

Volume Name: GATE02-SYSTEM
Size: 141.5 Gb
Volume Name: GATE02-S
Size: 1862.75 Gb

with sed/awk? I looked for answers for the only number output like:

echo "151934468096" | awk '{ byte =$1 /1024/1024**2 ; print byte " GB" }'

but can't figure out how to apply it to my case.

EDIT: I'd like to clarify my case. I have the following one-liner:

esxcfg-info | grep -A 17 "\\==+Vm FileSystem" | grep -B 15 "[I]s Accessible.*true" | grep -B 4 -A 11 "Head Extent.*ATA.*$" | sed -r 's/[.]{2,}/: /g;s/^ {12}//g;s/\|----//g' | egrep -i "([V]olume Name|^[S]ize:)"

which generates output above. I want to know what to add more after the last command to get the desired output.

Upvotes: 2

Views: 3287

Answers (2)

tripleee
tripleee

Reputation: 189467

printf "Volume Name: GATE02-SYSTEM\nSize: 151934468096\nVolume Name: GATE02-S\nSize: 2000112582656" |
awk '/^Size: / { $2 = $2/1024/1024**2 " Gb" }1'

Upvotes: 1

DevSolar
DevSolar

Reputation: 70293

Using (GNU) sed and bc:

... | sed 's@Size: \([0-9]*\)@printf "Size: %s" $(echo "scale = 2; \1 / 1024 ^ 3" | bc)GiB@e'
             ^^^^  ^^^^^^^^^^ ^^^^^^                    ^^^^^^^^^  ^^ ^^^^^^^^^^    ^^     ^
               1        2        3                          4       5      6         7     8
  1. Matching Size: lines.
  2. Capturing the number of bytes (potentially vulnerable if empty or zero, strengthen for production use)
  3. Replacing with printf output
  4. scale = sets the number of decimals for bc
  5. Using the sed capture group (number of bytes)
  6. The mathematical operation on the byte number
  7. Piping all that to bc for evaluation
  8. Telling sed to execute the "replace" part of the s statement in a subshell.

Another option is numfmt (where available, since GNU coreutils 8.21):

... | sed 's@Size: \([0-9]*\)@printf "%s" $(echo \1 | numfmt --to=iec-i --suffix=B)@e'

This doesn't give you control over the decimals, but "works" for all sizes (i.e. gives TiB where the number is big enough, and does not truncate to "0.00 GiB" for too-small numbers).

Upvotes: 3

Related Questions