Looking for a way to get the heading printed (awk related)

OS : HP Unix
Shell : Bourne shell

In my shop, HP-Unix is used. On big servers, I usually have an average of around 70 filesystems.
Since HP-Unix's df output is unreadable, I found the following awk script in the internet, which makes the df output human readable.

df -Pk | awk '{ 
 if ( NR == 1 ) { next } 
 if ( NF == 6 ) { print } 
 if ( NF == 5 ) { next } 
 if ( NF == 1 ) { 
 getline record; 
 $0 = $0 record 
 print $0 
 } 
 }' | awk '
BEGIN {print "Filesystem                                    Mount Point                 Total GB   Avail GB    Used GB  Used"
       print "--------------------------------------------- ------------------------- ---------- ---------- ---------- -----"}
END {print ""}
/dev/ || /^[0-9a-zA-Z.]*:\// {
printf ("%-45.45s %-25s %10.2f %10.2f %10.2f %4.0f%\n",$1,$6,$2/1024/1024,$4/1024/1024,$3/1024/1024,$5)
}'

And the output will be neat and readable like below.

Filesystem                                    Mount Point                 Total GB   Avail GB    Used GB  Used
--------------------------------------------- ------------------------- ---------- ---------- ---------- -----
/dev/vx/dsk/softdg/opt_oracle_goldengate      /opt/oracle/goldengate         39.71      37.41       2.30    6%
/dev/vx/dsk/goldengatedg/oradbs_goldengate_tr /oradbs/goldengate/trails     397.43     327.69      69.74   18%
/dev/vx/dsk/osbpdg/oradbs_osbp_dbf02_vol      /oradbs/osbp/dbf02            999.03     123.48     875.55   88%
/dev/vx/dsk/orasharedg/goldengatevol          /opt/orashare/goldengate       99.31      88.92      10.39   11%
/dev/vx/dsk/db1pdg/oradbs_db1pdg_dbf01_vol    /oradbs/db1p/dbf01           4499.57     696.52    3803.05   85%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf01_vol    /oradbs/wbmp/dbf01           4068.15     417.76    3650.39   90%
/dev/vx/dsk/osbpdg/oradbs_osbp_dbf01_vol      /oradbs/osbp/dbf01           3974.18     537.05    3437.13   87%
/dev/vx/dsk/db1pdg/oradbs_db1pdg_dbf03_vol    /oradbs/db1p/dbf03           3089.22    1016.54    2072.69   68%
/dev/vx/dsk/db1pdg/oradbs_db1pdg_dbf04_vol    /oradbs/db1p/dbf04           1992.35      66.75    1925.60   97%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf03_vol    /oradbs/wbmp/dbf03           1502.49      26.48    1476.01   99%
/dev/vx/dsk/compdg/oradbs_compdg_dbf01_vol    /oradbs/comp/dbf01           2003.60     665.98    1337.62   67%
/dev/vx/dsk/cntpdg/oradbs_cntpdg_dbf01_vol    /oradbs/cntp/dbf01            592.79     213.14     379.65   65%
/dev/vx/dsk/db1pdg/oradbs_db1pdg_dbf02_vol    /oradbs/db1p/dbf02           3976.67     199.40    3777.27   95%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf02_vol    /oradbs/wbmp/dbf02           1957.26    1361.08     596.18   31%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_fra_vol      /oradbs/wbmp/fra             1083.50    1079.28       4.23    1%
/dev/vx/dsk/db7pdg/oradbs_db7pdg_dbf01_vol    /oradbs/db7p/dbf01           3069.20     355.69    2713.51   89%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_rcv_vol      /oradbs/wbmp/rcv              136.51      52.36      84.15   62%
/dev/vx/dsk/orasharedg/logvol                 /opt/orashare/log              75.00      66.95       8.05   11%
.
.
.
.

But, lets say I want to know the filesystem free space info about the mount point "/oradbs/wbmp/dbf03" . I then pipe from the main output and grep for the the pattern wbmp like below

df -Pk | awk '{ 
 if ( NR == 1 ) { next } 
 if ( NF == 6 ) { print } 
 if ( NF == 5 ) { next } 
 if ( NF == 1 ) { 
 getline record; 
 $0 = $0 record 
 print $0 
 } 
 }' | awk '
BEGIN {print "Filesystem                                    Mount Point                 Total GB   Avail GB    Used GB  Used"
       print "--------------------------------------------- ------------------------- ---------- ---------- ---------- -----"}
END {print ""}
/dev/ || /^[0-9a-zA-Z.]*:\// {
printf ("%-45.45s %-25s %10.2f %10.2f %10.2f %4.0f%\n",$1,$6,$2/1024/1024,$4/1024/1024,$3/1024/1024,$5)
}' | grep wbmp

Now, the output loses the heading and only shows the below (understandably)

/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf01_vol    /oradbs/wbmp/dbf01           4068.15     417.76    3650.39   90%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf03_vol    /oradbs/wbmp/dbf03           1502.49      26.48    1476.01   99%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf02_vol    /oradbs/wbmp/dbf02           1957.26    1361.08     596.18   31%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_fra_vol      /oradbs/wbmp/fra             1083.52    1077.55       5.97    1%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_rcv_vol      /oradbs/wbmp/rcv              136.51      52.36      84.15   62%

Is there any way I can get the heading printed as well, so that when I pipe and grep like above, I can still get the heading printed. Expected output shown below

Filesystem                                    Mount Point                 Total GB   Avail GB    Used GB  Used
--------------------------------------------- ------------------------- ---------- ---------- ---------- -----
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf01_vol    /oradbs/wbmp/dbf01           4068.15     417.76    3650.39   90%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf03_vol    /oradbs/wbmp/dbf03           1502.49      26.48    1476.01   99%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_dbf02_vol    /oradbs/wbmp/dbf02           1957.26    1361.08     596.18   31%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_fra_vol      /oradbs/wbmp/fra             1083.52    1077.55       5.97    1%
/dev/vx/dsk/wbmpdg/oradbs_wbmpdg_rcv_vol      /oradbs/wbmp/rcv              136.51      52.36      84.15   62%

without going into why the script has 2 awk-s piped together....

You can redirect your header lines to stderr and it will come out when you grep your stdin.

E.g.

BEGIN {
   stderr="cat 1>&2"
   print "Filesystem                                    Mount Point                 Total GB   Avail GB    Used GB  Used"  | stderr
   print "--------------------------------------------- ------------------------- ---------- ---------- ---------- -----" | stderr
}

see if it helps.

1 Like

Your tweak did the trick.
Thank You vgersh99.

1 Like

You could always use either egrep or grep -E depending which works on your server with this as your grep:-

......... | grep -E -- "----|Filesystem|wbmp"

This lets you search for a regular expression, so I've added three elements, pipe delimited.

I hope that this helps,
Robin

1 Like

This is a better solution. "Output should go to stdout, errors should go to stderr" should be every programmer's mantra. Well, one of their mantras, at least. :wink:

Using a grep pattern that matches all lines (perhaps via multiple -e options or similar) is best.

Another option is to pipe the output into a command that copies the appropriate number of lines to stdout and then passes the remaining lines to grep. Such as:

your_script | (read line; echo "$line"; read line; echo "$line"; grep ...)

This could also be done using sed if you tell it to quit as soon as the first two lines are processed (untested, but I think I have the command block correct...?):

your_script | (sed -ne '1,2{p;q;}'; grep ...)
2 Likes

Are you sure there is no sed version out there that prefetches line 3? Then it would be lost for the grep.
I am even in doubt for head -2
If the grep is without options then you can entirely switch to sed
your_script | sed -n '1,2p; /wbmp/p'
To ensure that line 1 and 2 are not considered for the match (and eventually reprinted):
your_script | sed -n '1,2{p;d;}; /wbmp/p'

2 Likes

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.