Rounding a number in awk

5,336

Solution 1

You could do something like:

memory=$(
  LC_ALL=C free -h | awk '
    /^Mem/ {
      suffix = $2
      sub(/[0-9.]*/, "", suffix)
      printf "%.0f%sB\n", $2, suffix
    }'
)

(LC_ALL=C to make sure the numbers are printed using the . decimal radix (3.7G would be output as 3,7G in locales using comma as the decimal radix)).

On GNU/Linux systems, you can also do:

memory=$(
  awk '/^MemTotal/{print $2*1024}' < /proc/meminfo |
    numfmt --to=iec --format=%0f --suffix=B
)

Or:

memory=$(
  free -h | awk '/^Mem/{print $2}' |
    numfmt --from=iec --to=iec --format=%0f --suffix=B
)

(that one coping with locales where the decimal radix is not .).

Note that free on Linux reports that MemTotal field of /proc/meminfo. As per proc(5), that's the total usable RAM (i.e., physical RAM minus a few reserved bits and the kernel binary code). For the physical RAM, and for PCs, as pointed out by @StephenKit, you may be better off using dmidecode to get the information from the BIOS, though you'd need superuser privileges for that:

physical_memory=$(
  sudo dmidecode -t memory |
    awk '$1 == "Size:" && $2 ~ /^[0-9]+$/ {print $2$3}' |
    numfmt --from=iec --suffix=B |
    awk '{total += $1}; END {print total}' |
    numfmt --to=iec --suffix=B --format=%0f
)

Solution 2

$ echo "3.7" | awk '{printf("%d\n",$1 + 0.5)}'
4

Solution 3

If you want to round to 2 decimal, here are some simple examples:

echo "12345.12345" | nawk '{printf ("%.2f\n", $1+0.005)}'
echo "12345.345" | nawk '{printf ("%.2f\n", $1+0.005)}'
Share:
5,336

Related videos on Youtube

TheSebM8
Author by

TheSebM8

Just a average metalhead wanna be IT guy. Hopefully gonna be a SysAdmin one day

Updated on September 18, 2022

Comments

  • TheSebM8
    TheSebM8 almost 2 years

    I’m trying to find a way to round up a few numbers.

    The topic I found: https://stackoverflow.com/questions/2395284/round-a-divided-number-in-bash

    I am using the following command in my bash script..

    free -h | gawk '/Mem:/{print $2}' | awk 'FNR == 1 {print $1 "B"}')

    The following code will show me how much in total Memory i have installed. Currently, im getting 3.7GB. The problem is, i need this to be rounded up to 4GB.

    I have a script that requests my machine a bunch of info and will echo it all out. (Prolly should use something different but haven't tried anything else yet as this is one of my projects that i am working on.

    memory=$(free -h | gawk '/Mem:/{print $2}' | awk 'FNR == 1 {print $1 "B"}')

    echo $memory

    Right now it echo's out 3.7GB as mentioned below. I'v tried it different ways but can't seem to get it to 4GB.

    • Stephen Kitt
      Stephen Kitt over 6 years
      This doesn’t address your rounding question, but see this question to correctly determine the amount of installed memory.
    • TheSebM8
      TheSebM8 over 6 years
      Sadly can't install new software. I need to use the ones that come with Debian.
    • Stephen Kitt
      Stephen Kitt over 6 years
      dmidecode is priority important so it should be present on most Debian systems. You can’t guarantee you’ll get the correct result from free (especially free -he.g. on systems with 10 GiB of RAM or more, it will lose a full gibibyte).
  • TheSebM8
    TheSebM8 over 6 years
    Can't use it like this. I need a way that does it for every different machine.
  • TheSebM8
    TheSebM8 over 6 years
    Sadly this still gives me 3.7GB
  • Stéphane Chazelas
    Stéphane Chazelas over 6 years
    @TheSebM8. How come? Does your awk print 3.7 for awk 'BEGIN{printf "%.0f\n", 3.7}'?
  • Kusalananda
    Kusalananda over 6 years
    @TheSebM8 You probably made a typo in that case.
  • TheSebM8
    TheSebM8 over 6 years
    @kusalanda no, i did notmake any typos. I copied what Stephane gave me. StéphaneChazelas that one does round it to 4.
  • Stéphane Chazelas
    Stéphane Chazelas over 6 years
    @TheSebM8, is it possible that you get 3,7G instead of 3.7 (see edit)? Otherwise, like Kusalananda, I can't explain it other than with a typo.
  • TheSebM8
    TheSebM8 over 6 years
    @StéphaneChazelas All of the commands you gave worked perfectly. Thank you!
  • Stéphane Chazelas
    Stéphane Chazelas over 6 years
    @StephenKitt, under what condition would they underestimate by 1 GiB (other than 1.1T rounded to 1T?)
  • TheSebM8
    TheSebM8 over 6 years
    Won't be having any server with over 1 TB RAM, so i'd say this works good :P
  • Stephen Kitt
    Stephen Kitt over 6 years
    Basically there’s no fool-proof way to go from MemTotal to the amount of memory really installed. You need something like dmidecode instead.
  • TheSebM8
    TheSebM8 over 6 years
    @StéphaneChazelas how would you put your LC_ALL command into a bash script so if you " printf $memory it would print ut the result?
  • Stéphane Chazelas
    Stéphane Chazelas over 6 years
    @TheSebM8, see edit