formatting of df -k

Hello,

I am developing a platform Independant tool that should work for all major unix flavors outlined in this forum(Solaris,Linux, AIX, HPUX, SCO,BSD)

Therefore, in order to cover all types of user community, I have deliberately posted the same message on every forum. Please do not think of this as spamming multiple forums. This is one of a kind request and I do not wish to continue with this approach(of spreading same post to multiple forums)

Now the question:

The output on df -k on HP looks like below

/r01                   (/dev/vgprj2app/vr01   ) : 207501014 total allocated Kb
                                                  33261948 free allocated Kb
                                                  174239066 used allocated Kb
                                                        83 % allocation used
/tmp                   (/dev/vg00/lvol4       ) : 11798652 total allocated Kb
                                                  11774476 free allocated Kb
                                                     24176 used allocated Kb
                                                         0 % allocation used
/usr                   (/dev/vg00/lvol7       ) :  4960928 total allocated Kb
                                                   2534000 free allocated Kb
                                                   2426928 used allocated Kb

On Solaris and others the same df -k will show the output in a very different format.

I am looking to massage above output to a comma delimited format to stream line the same format that will work as an input to Oracle databases.

Mount,totalAllocated,FreeAllocated,usedAllocated,percent
"/r01",207501014,33261948,174239066,83
"/tmp",11798652,11774476,24176,0
"/usr",4960928,2534000,2426928,80

How can I massage the df -k ouput formats of various kinds into the one mentioned above using shell scripts? I heard that awk utility can do this, but I just dont know awk programming :frowning:

Thanks,
D

If you want to make a truly crossplatform tool, you'd do better to learn the API's instead of processing the df -k output.

I'm no Perl programmer so please be kind. :slight_smile:

I also wanted df output that would work on AIX, HP-UX and Linux. So I run the df command and massage the input so that the output is consistent.

My approach was to write a bit a of code for each OS.

Ex:

$SYS_NAME=`uname -s`;

if ($SYS_NAME =~ "AIX") {
   $SYS_TYPE=1;
   `/usr/bin/df -k | /usr/bin/sort +6 >$FILE`;
}
elsif ($SYS_NAME =~ "HP-UX") {
   $SYS_TYPE=2;
   `/usr/bin/bdf -i >$FILE`;
}
elsif ($SYS_NAME =~ "Linux") {
   $SYS_TYPE=3;
   `/bin/df -kP >$FILE`;
}
else {
   print "Unknown system: $SYS_NAME.";
   exit -1;
}

Then:

open (DF, $FILE) || die "Can't Open File: $FILE\n";
while (defined ($_ = <DF> )){

   ###########################################################################
   # AIX
   ###########################################################################
   if ($SYS_TYPE == 1){
      ($FS, $BLOCKS, $FSFREE, $FSUSED, $IUSED, $PIUSED, $MOUNT) = split;
      $FSUSED=~s/([0-9])\%/$1/;
      $PIUSED=~s/([0-9])\%/$1/;

   }


...

   ###########################################################################
   # Every OS
   ###########################################################################
   if ($MOUNT eq "\/") {
      $FS = "Root"
   }
   elsif ($FS=~/:/) {
      $FS1 = "NFS from " . $FS; $FS=$FS1
   }

   if ($FSUSED >= 90)
      $FSUSED = "*$FSUSED*";
   }

   if ($PIUSED > 60) {
      $PIUSED = "*$PIUSED*";
   }

   if ($BLOCKS ne "Size (MB)") { $BLOCKS /= 1024 };
   if ($FSFREE ne "Free (MB)") { $FSFREE = int ($FSFREE /= 1024) };

   if ( (not $MOUNT=~"\/u\/") && (not $MOUNT=~"Mounted") || ($FS=~"NFS") ) {
      printf "%-38s %-9d %-9d %-7s %-7s %-11s\n",$MOUNT, $BLOCKS, $FSFREE, $FSUSED, $PIUSED, $FS;
   }
}

Which results in:

mi_df
======================================================================================================================================================
Filesystem                             Size (MB) Free (MB) %Used   %Iused  Mount
======================================================================================================================================================
/proc                                  0         0         -       -       /proc
/                                      512       389       24      12      Root
/home                                  8192      4637      44      7       /dev/hd1
/home/dbdumps                          1097728   320906    71      1       NFS from unxr1_sw:/home/dbdumps
/nim_export                            65536     7909      88      4       /dev/nim_lv
/opt                                   2048      742       64      14      /dev/hd10opt
/tftpboot                              128       75        41      1       /dev/fslv00
/tmp                                   256       250       3       1       /dev/hd3
/usr                                   5120      2561      50      11      /dev/hd2
/var                                   1024      540       48      9       /dev/hd9var
======================================================================================================================================================

Thank you purdym for the detail posting. I tried to compile your code as is on my HPUX Box and it gives following error:

shell.sh" 60 lines, 1454 characters
daahpdev: dev/home/rvaishna$ shell.sh
shell.sh: =HP-UX:  not found.

when I do uname -s from $ prompt it gives me exactly HP-UX. Not sure why it is not working from shell script.

Any idea why this error is coming?

Thanks,
Darsh

That would be the problem then. You never compile a shell script.

More seriously, that is a perl script, and you seem to be running it in shell...

Thank you for the reply. I actually meant while executing the shell script.

As you have probably figured out by now, I am a novice to shell programming and perl.

Is there anyway I can achieve a CSV(Comma separated values) tabular output of df/bdf command using simply shell programming?

Thanks,
Darsh

So I didn't post the entire complete script on purpose. I was trying to give you and idea of how it could be done.

You can use the same logic in shell scripting. ie. test for what OS your using and run slightly different code for each OS. And hopefully there is some common code.

I will say that it is more complicated but possible to write code to run on multiple OSs.

The format of the HP-UX command "bdf" is much easier to work and it looks just like "df -k" from some other unix versions.

Here is the HP-UX code. This can be inserted into the "..." in my first post:

   ###########################################################################
   # HP-UX
   ###########################################################################
   elsif ($SYS_TYPE == 2){
      if ($CONT == 0){
         ($FS, $BLOCKS, $DUMMY1, $FSFREE, $FSUSED, $IUSED, $IFREE, $PIUSED, $MOUNT) = split;
      }
      elsif ($CONT == 1){
         ($BLOCKS, $DUMMY1, $FSFREE, $FSUSED, $IUSED, $IFREE, $PIUSED, $MOUNT) = split;
         $CONT=0;
      }
      if ($BLOCKS eq "") {
         $CONT=1;
         next;
      }

      $FSUSED=~s/([0-9])\%/$1/;
      $PIUSED=~s/([0-9])\%/$1/;
   }

Maybe try the -P portability option, where possible, to make df use the POSIX output format.