0

I have to check the free space on a disk volume and am using the command df -h, which produces this output:

Filesystem            Size  Used Avail Use% Mounted on
/dev/md0               27G   24G  2.1G  92% /
udev                  506M  112K  506M   1% /dev
/dev/sda1             102M   40M   63M  39% /boot

This piece of script

my (@space, @freesp);
@space = grep /\/dev\/md0/,`df -h`;
print "@space\n";

is giving me

/dev/md0               27G   24G  2.1G  92% /

Which I can split on whitespace giving the values in $freesp[0], $freesp[1] etc.

But I want to remove or replace that G with white space, so that I can compare $freesp[3] with some value and can proceed with my script.

So what is the regex I have to use for this to happen, or is there any other better way to do this?

This code is working for me, but I'm looking in a direction I have mentioned.

#!/usr/bin/perl

use strict;
use warnings;

my (@space, @freesp);

@space = grep /\/dev\/md0/, `df`;

print "@space\n";

for (@space) {
    chomp;
    @freesp = split /\s+/, $_;
}

if ($freesp[3]/1024/1024 < 2.0) {
    print "Space is less\n";
}
else {
    print "Space is OK\n";
}

#print ($freesp[3]/1024/1024);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mviswa
  • 147
  • 1
  • 1
  • 10

1 Answers1

8

The real solution is not to use the -h option to df if you intend to parse the output with a script. That way, the output won't contain the "human-readable" K / M / G suffixes in the first place.

You may wish to instead use the -B1 option, which causes all sizes to be reported in bytes.


Edit: To answer the literal question, you could remove the suffixes and rescale the values appropriately like this:

my %units = (K => 2**10, M => 2**20, G => 2**30, T => 2**40,
             P => 2**50, E => 2**60, Z => 2**70, Y => 2**80);

s/^(\d+(?:\.\d+)?)([KMGTPEZY])$/$1 * $units{$2}/e for @freesp[1 .. 3];

However, using the -B1 switch instead of -h would give the same result more easily, not to mention more accurately and reliably.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
  • Ya i know that using the df and dividing with 1024's to get our O/p , but i am wondering if there's any way relative to what i mentioned .........that is if a digit followed by G then replace G/M/K with white space – mviswa Mar 13 '13 at 06:30
  • **#!/usr/bin/perl use strict; use warnings; my (@space,@freesp); @space=grep /\/dev\/md0/,`df`; print "@space\n"; for(@space){ chomp; @freesp=split /\s+/ ,$_; } if ($freesp[3]/1024/1024 < 2.0){ print "Space is less\n"; }else { print "Space is OK\n"; } #print ($freesp[3]/1024/1024); ** this code is working for me but im looking in a direction i have mentioned ........ – mviswa Mar 13 '13 at 06:41
  • 2
    @mViswa What can you possibly hope to gain by using human readable format and deleting `G/M/K` and then comparing? Don't use the `-h` option if you intend to parse the output with a script. – TLP Mar 13 '13 at 06:47
  • 4
    @mViswa: The reason to not use `-h` and rely on blanking out the letter is because a disk might fill up and report 700M free. 700M is a lot less than 20G, but, when you blank out the letters, 700 > 20. – Dave Sherohman Mar 13 '13 at 09:16