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.
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.
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.