简体   繁体   中英

Calculate the Disk Space with awk

I am trying to calculate the total disk space on a UNIX (Solaris) host with this script but I have to use awk twice. Is there a better way to do this?

> root# iostat -En | grep ^Size 
Size: 146.81GB <146810536448 bytes>     
Size: 0.00GB <0 bytes> 
Size: 107.37GB <107374182400 bytes> 
Size: 107.37GB <107374182400 bytes>
Size: 107.37GB <107374182400 bytes> 
Size: 107.37GB <107374182400> bytes>
Size: 21.47GB <21474836480 bytes>

Here is the awk syntax I am applying:

    # iostat -En | grep ^Size | awk '{print $2}' | cut -d"G" -f1  | awk '{sum+=$1} END {print sum}'

> 29412.7

Can we add a scaler as well to have the values in better format for decimal presentation?

awk will select for ^Size lines (eliminating grep ) and remove the G for you:

iostat -En | awk '/^Size/{sum+=$2} END {print sum}'
361.55

The expression sum+=$2 forces awk to treat the second field as a number. This means that alpha characters are removed.

More accurate calculation

The third field in your iostat output appears to contain actual bytes. That eliminates the need to convert gigabytes, megabytes, etc. To use this field:

iostat -En | awk -F'[ \t<>]+' '/^Size/{sum+=$3} END {printf "%sGB\n", sum/1e9}'
361.559GB

The option -F'[ \\t<>]+' tells awk to treat any combination of space, tab, or angle brackets as field separators. This has the effect of removing the < and > from the third field so that the third field can be directly treated as a number.

More on awk's variable conversion

One can directly test awk's conversion from string to number with commands like:

$ echo '132G' | awk '{print $1+0}'
132
$ echo '<132G' | awk '{print $1+0}'
0

In the latter case, the < caused the conversion to number to fail. That is why the field separator was changed in the code above to remove the < from the fields.

John1024's simple answer will work with the sample output you provided but might miss some disks in the general case. There is actually no guarantee for Size to be the first token to appear in iostat output, eg:

# iostat -E
cmdk0     Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Model: VBOX HARDDISK   Revision:  Serial No: VB7dd0d7cc-4f38 
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
Illegal Request: 0

Here is then a reliable way to compute the size of attached devices by extracting the size in bytes wherever it appears on iostat output:

iostat -E | nawk '/Size:/ {
  sub(".*Size:[^<]*<",""); # Remove the leading part of the line up to the first "<" following "Size:"
  sub(" bytes>.*$","");    # Remove the trailing part of the line "from bytes>"
  sum+=$0                  # The line now only contains the size in bytes, sum it to the previous ones (if any)
  cnt++                    # Count the number of devices
}   
END {
  print cnt,"devices:"
  # Print the size:
  # - in gigabytes (1 GB = 1000000000 bytes = 10^9 bytes)
  # - in gibibytes (1 GiB = 1024*1024*1024 bytes = 2^30 bytes)
  # - in bytes
  printf("%0.3f GB (%.3f GiB, %s bytes)\n",sum/1e9,sum/2e30,sum);
}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM