Operating System - HP-UX
1752594 Members
2846 Online
108788 Solutions
New Discussion юеВ

Re: awk on vgdisplay output

 
SOLVED
Go to solution
Rasheed Tamton
Honored Contributor

awk on vgdisplay output

I have a big file with vgdisplay output a sample of which is below:

---
VG Name /dev/vgbackup
Max PV 16
Cur PV 2
Max PE per PV 59466
PE Size (Mbytes) 16
VG Name /dev/vgtbl10
Max PV 16
Cur PV 16
Max PE per PV 1023
PE Size (Mbytes) 4
VG Name /dev/vgredo
Max PV 16
Cur PV 10
Max PE per PV 1016
PE Size (Mbytes) 4
VG Name /dev/rdvgcp
Max PV 16
Cur PV 3
Max PE per PV 13071
PE Size (Mbytes) 16
----------
I need the Record Separator as VG Name. That means each record is starting from VG Name up to PE Size (5 lines).

VG Name /dev/vgbackup
Max PV 16
Cur PV 2
Max PE per PV 59466
PE Size (Mbytes) 16

I need to use awk which should consider the first five lines as a record then print it on a single line separated by comma (,)

So the output should be something like this:
VG Name,/dev/vgbackup,Max PV,16,Cur PV,2,Max PE per PV,59466,PE Size (Mbytes),16

Thanks
Rasheed.
8 REPLIES 8
Steve Steel
Honored Contributor

Re: awk on vgdisplay output

Hi


Since 5 lines each time

let x=0
outline=""
cat $1|while read line
do
let x=$x+1
if [ "$x" -eq 1 ]
then
outline=$line
else
outline=$outline","$line
fi
if [ "$x" -eq "5" ]
then
echo "$outline"
let x=0
fi
done


File is parameter

Steve Steel
If you want truly to understand something, try to change it. (Kurt Lewin)
Sanjay Kumar Suri
Honored Contributor

Re: awk on vgdisplay output

Assuming data is stored in a file data, then

for i in `cat data`
do
if [ $i = "VG" ]
then
echo
fi
echo "$i \c"
done
echo

Note: This script does not put , (comma).

sks
A rigid mind is very sure, but often wrong. A flexible mind is generally unsure, but often right.
Muthukumar_5
Honored Contributor
Solution

Re: awk on vgdisplay output

You can get your results using the following awk of ,

# awk '{ if ( NR %5 == 4 ) printf $1" "$2" "$3" "$4","$5","
if ( NR %5 == 0 ) printf $1" "$2" "$3","$4"\n"
if ( NR %5 == 1 || NR %5 == 2 || NR %5 == 3 )
printf $1" "$2","$3","
}' filename

Results
--------

VG Name,/dev/vgbackup,Max PV,16,Cur PV,2,Max PE per PV,59466,PE Size (Mbytes),16
VG Name,/dev/vgtbl10,Max PV,16,Cur PV,16,Max PE per PV,1023,PE Size (Mbytes),4
VG Name,/dev/vgredo,Max PV,16,Cur PV,10,Max PE per PV,1016,PE Size (Mbytes),4
VG Name,/dev/rdvgcp,Max PV,16,Cur PV,3,Max PE per PV,13071,PE Size (Mbytes),16
Easy to suggest when don't know about the problem!
Rodney Hills
Honored Contributor

Re: awk on vgdisplay output

If you would be interested in a perl one-liner-

perl -ne 'chomp; $line=/^VG Name/ ? $_ : $line.",".$_; print $line,"\n" if /^PE Size/' vgoutputfile

HTH

-- Rod Hills
There be dragons...
rmueller58
Valued Contributor

Re: awk on vgdisplay output

I did something similar to do a mass build of different vgs..

#/home/scripts/volbuild
# more volbuild
cd /pei/peitools/bin
echo 'This script will build and create database space,
Please not you should know about how much disk space is required
and available.. Below is a listing of free space in existing
Volume Groups'


echo "Enter Enter District ID:"
read district
for vg in `grep "LV Name" vg.txt |awk '{print $3}' |grep dbs |grep -v vg00 |grep -v log |grep -v root |grep -v tmp |grep
$district`
do
vgrp=`lvdisplay $vg |grep "VG Name"|awk '{print $3}'`
echo -------- Logical Volume `lvdisplay $vg |grep "LV Name"` --------
lvdisplay $vg |grep "LV Name"
echo $vgrp
lvdisplay $vg |grep "LV Size"
vgdisplay $vgrp |grep Free
export dbspace=`lvdisplay $vg |grep "LV Name" |awk '{print substr($3, 11, 6)}'`
export vgrp=`lvdisplay $vg |grep "VG Name"|awk '{print $3}'`
export nvol=`lvdisplay $vg |grep "LV Name" |awk '{print substr($3, 17, 1)}'`


if [ -z "$nvol" ]
then export nvol=0
fi

export i=`expr $nvol + 1`

done

echo "Enter Size of Volume"
read size
export size
echo lvcreate -L $size -n $dbspace$i $vgrp
cd $vgrp
echo chown informix:informix r$dbspace$i
echo chmod 660 r$dbspace$i
export fname=r$dbspace$i

cd /dev/online
#
ls $fname


echo ln -s $vgrp/$fname $dbspace$i
echo onspaces -a $dbspace$i -p /dev/online/$fname -o 0 -s "$size"000
Hein van den Heuvel
Honored Contributor

Re: awk on vgdisplay output


Hmmm, my vgdisplay (11.23) shows more lines. For example:

VG Name /dev/vg00
VG Write Access read/write
VG Status available
Max LV 255
Cur LV 8
Open LV 8
Max PV 16
Cur PV 1
Act PV 1
Max PE per PV 4328

So I would recommend you protect against that and select 'just what you need'.

My perl 'one-liner' woudl be explicit about matches:

vgdisplay -v | perl -ne '
if (/^(VG Name|Max PV|Max PE per PV)\s+(\S+)/)
{ $x .= "$1,$2," }
if (/(PE Size \(Mbytes\))\s+(\d+)/){print "$x$1,$2\n"; $x=""}'


This says:
If the string starts with one of 4 expliciti strings, then glue that string , plus a comma, plus the next series of non-whitespace, plus a comma to a workstring 'x'.
Look explicitly for the last match and print temp + last.

Result for me:

VG Name,/dev/vg00,Max PV,16,Max PE per PV,4328,PE Size (Mbytes),16
VG Name,/dev/vg_oltp,Max PV,16,Max PE per PV,65535,PE Size (Mbytes),32
:


hth,
Hein.





Hein van den Heuvel
Honored Contributor

Re: awk on vgdisplay output


Just for yucks...

It bothered me I could not come up with a nice generic way to catch the words before the value. So without hardcoding files numbers/names.

first potential solution... just take enough interesting bytes for the name, then trim some.

awk '{n=substr($0,1,22);gsub(/ +/," ",n);x=x n "," $NF ","}/^PE S/{sub(/.$/,"",x); print x;x=""}'


Second potential solution... first collapse all multiple spaces to single space. The use the position of the last field as the end of the name + 2:

awk '{gsub(/ +/," ");x=x substr($0,1,index($0,$NF)-2) "," $NF ","}/^PE S/{sub(/.$/,"",x); print x;x=""}'


Ok.... back to real work.

Hein.

Rory R Hammond
Trusted Contributor

Re: awk on vgdisplay output

Based on the output shown this is AWK ugly.

You want a ,(comma) as seperator between the field label and the data.
IE:
fieldname, data, fieldname, data, etc

This worked on my system:
vgdisplay | awk '
( $0 ~ /VG Name/ ) {
for (i = 1; i <= 4; i++)
{
while (gsub(/ /," "));
fields=split($0,data," ")
for (f = 1; f < fields; f++)
printf("%s ",data[f])
printf(",%s,",data[fields])
getline
}
while (gsub(/ /," "));
fields=split($0,data," ")
for (f = 1; f < fields; f++)
printf("%s ",data[f])
printf(",%s\n",data[fields])
}
'

vgdisplay | awk ' #imput stream to awk
( $0 ~ /VG Name/ ) { # find first record

for (i = 1; i <= 4; i++) #next four lines
{
while (gsub(/ /," ")); #reduce white space

fields=split($0,data," ") #split into fields
#print all the line fields except last
#this is field name
for (f = 1; f < fields; f++)
printf("%s ",data[f])
#print a comma and then the data field
printf(",%s,",data[fields])
getline
}
#Do the last line as above ending in a
# linefeed
while (gsub(/ /," "));
fields=split($0,data," ")
for (f = 1; f < fields; f++)
printf("%s ",data[f])
printf(",%s\n",data[fields])
}

'
There are a 100 ways to do things and 97 of them are right