Host name in front of pkginfo output

hello all

I am trying to create a comma seperated file of the pkginfo command. The follwoing works pretty well.

pkginfo -l | egrep '(BASEDIR|NAME|VERSION)' | awk '{print}' ORS=', '

however, there are two issues.

1, For some reason it does not load into excel properly. It loads as one huge row of data instead of multple rows.

2, I also need the host name in the output. the host name should be at the beging of every record. the disired result should be something like:

HOSTNAME, NAME, VERSION, BASEDIR
 
example
 
svr331web, NAME:  cas_cpsampleconf - Class action script cpsampleconf,    VERSION:  1.42,REV=2010.11.26,    BASEDIR:  /

I have been attempting to use the following script to accomplish this:

for PNAME in `pkginfo -l  | egrep '(NAME|VERSION|BASEDIR)' | awk '{print}' ORS=', '`
do
 echo "`uname -n`, $PNAME"  
done

however the ouput is not what i was looking for. It comes out as:

svr331web, NAME:  cas_cpsampleconf 
svr331web, Class,
svr331web, action ,
svr331web, script,
svr331web, cpsampleconf,   
svr331web, VERSION:,
svr331web, 1.42,REV=2010.11.26,    
svr331web, BASEDIR:  /,

Any ideas on how I can get the desired output?

Thanks.

Don't use a comma as an ouput field separator, try "|"

Because your heading shows 4 fields, yet your output, based on the use of the "," shows more. This implies a "," is in the data.

Hi

This did not seem to help with issue 1 or 2.

thanks

---------- Post updated at 05:51 PM ---------- Previous update was at 10:44 AM ----------

It seems I am making some progress...Then again I can never be sure.

I found a some sed syntax that will delete white spaces from the output.
I seem to be making progress, as the data shows up in rows on excel now. The server name also shows up where I want it. However, only part of the data is loading to excel and olny a few rows have the server name in the output. the code im using is

for PNAME in `pkginfo -l | egrep '(NAME|VERSION|BASEDIR)' | sed 's/  *//g' | awk '{print}' ORS=',' `
do
 echo "`uname -n`, $PNAME" 
done

I'm considering to use sed to simply replace NAME with servername, NAME.
however that would give me an extra comma that I would not know what to do with.

If any one knows how to do this please post a response.

thx

Allow me to clarify my request for this post.

the command pkginfo -l, provides a long listing of all packages installed on a solaris system. the output would look similar to this:
 
PKGINST:  SUNWzsh
      NAME:  Z shell (zsh)
  CATEGORY:  system
      ARCH:  sparc
   VERSION:  11.10.0,REV=2005.01.08.05.16
   BASEDIR:  /
    VENDOR:  Oracle Corporation
      DESC:  Z shell (zsh)
    PSTAMP:  sfw10-patch20110415091259
  INSTDATE:  Jul 17 2013 15:07
   HOTLINE:  Please contact your local service provider
    STATUS:  completely installed
     FILES:      594 installed pathnames
                   6 shared pathnames
                   1 linked files
                  32 directories
                  30 executables
                5585 blocks used (approx)
 
   PKGINST:  TWeagent
      NAME:  Tripwire Enterprise Agent
  CATEGORY:  application
      ARCH:  sparc
   VERSION:  8.2.3
   BASEDIR:  /usr/local/tripwire/te/agent
    PSTAMP:  tripwire
  INSTDATE:  Aug 25 2013 12:03
    STATUS:  completely installed
     FILES:      904 installed pathnames
                 123 directories
                 762 executables
              352571 blocks used (approx)
 
   PKGINST:  samgr-client
      NAME:  SEA client support sunOS v5
  CATEGORY:  SAT
      ARCH:  sparc
   VERSION:  2.4.1.3
   BASEDIR:  /
    VENDOR:  IBM
    PSTAMP:  Wed Mar  9 22:18:10 MST 2011
  INSTDATE:  Apr 22 2012 01:37
    STATUS:  completely installed
     FILES:       12 installed pathnames
                   1 shared pathnames
                   4 directories
                   8 executables
                 419 blocks used (approx)
 
....so on and so forth for all packages....

I dont need all the output. I am interested in capturing only 3 pieces of information, which are NAME,VERSION, and BASEDIR. Im my limited understanding, all these three pieces of information would make up a record.
The goal is to insert the server name in front of every record and dump the data into a comma seperated file. Once we have all the data from all our servers will will combine them into an excel spread sheet(comman delimited) for review. An example of the desired output is as follows:

servername, NAME, VERSION,BASDIR
servername, NAME, VERSION,BASDIR
servername, NAME, VERSION,BASDIR
so on and so forth....

so far I have been able to insert the commas with the following script:

pkginfo -l | egrep '(BASEDIR|NAME|VERSION)' | sed 's/  *//g' | awk '{print}' ORS=','

which produces the following output...

NAME:RSAAccessManagerAgent4.8forSunJavaSystemWebServer,VERSION:4.8,BASEDIR:/opt,NAME:cas_cpsampleconf-Classactionscriptcpsampleconf,VERSION:1.42,REV=2010.11.26,BASEDIR:/,NAME:cas_cptemplates-Classactionscriptcptemplates,VERSION:1.49,
.....so on and so forth for all the packages......

I have discovered that a carriage return may be needed.

at this point I seem to be stuck. I was able to insert the server name
but only for a few records. For some reason it will insert the server neame every 40th record. The code I was using to do this is:

for PNAME in `pkginfo -l | egrep '(NAME|VERSION|BASEDIR)' | sed 's/  *//g' | awk '{print}' ORS=',' `
do
 echo "`uname -n`, $PNAME" 
done

Any assistance would be greatly appreciated.

on a side not, are there any books i should be reading for scripting?

Try something like:

host=$(uname -n)
pkginfo -l | /usr/xpg4/bin/awk -v host="$host" '
/NAME:/ {
	gsub(/(^ *NAME: *)|( *$)/, "")
	printf("%s,\"%s\",", host, $0)
	next
}
/VERSION:/ {
	gsub(/(^ *VERSION: *)|( *$)/, "")
	printf("\"%s\",", $0)
	next
}
/BASEDIR:/ {
	gsub(/(^ *BASEDIR: *)|( *$)/, "")
	print
}'

Note that you can't have a comma in a field in a comma separated file unless the fields that contain commas in the data are quoted. This script quotes the NAME and VERSION fields since it seems doubtful that the hostname and BASEDIR fields will ever contain commas. (Or, if they do, it should be obvious how to add the quotes if they are needed for those fields.) For the input shown, you should get something like the following from the above script:

HostName,"Z shell (zsh)","11.10.0,REV=2005.01.08.05.16",/
HostName,"Tripwire Enterprise Agent","8.2.3",/usr/local/tripwire/te/agent
HostName,"SEA client support sunOS v5","2.4.1.3",/

The script you provide looks really good. the only problem is that the host name does not seem to be coming out.

,"ZFS (Root)","11.10.0,REV=2006.05.18.02.15",/
,"ZFS (Usr)","11.10.0,REV=2006.05.18.02.15",/
,"The Info-Zip (zip) compression utility","11.10.0,REV=2005.01.08.05.16",/
,"The Zip compression library","11.10.0,REV=2005.01.08.05.16",/
,"Solaris Zones (Root)","11.10.0,REV=2005.01.21.15.53",/
,"Solaris Zones (Usr)","11.10.0,REV=2005.01.21.15.53",/
,"Z shell (zsh)","11.10.0,REV=2005.01.08.05.16",/
,"Tripwire Enterprise Agent","8.2.3",/usr/local/tripwire/te/agent
,"SEA client support sunOS v5","2.4.1.3",/
....so on and so forth.....

any chance we can get the host name at the begining?

---------- Post updated at 11:03 AM ---------- Previous update was at 07:05 AM ----------

Hi

Don, This issue has been resolved. is it possible you can explain your code? It would be a great help to me. Also are there any books you recomend I read? or did you get your understanding of scripting from experience?

to resolve my issue, I added the following to your code.

 >> /tmp/tmp.pkg
sleep 10
cat /tmp/tmp.pkg | while read LINE
do 
   echo "`uname -n` $LINE" >> /tmp/`uname -n`.pk
done

so the final code looks like this:

rm /tmp/tmp.pkg
rm /tmp/`uname -n`.pk
#host=$(uname -n)
pkginfo -l | /usr/xpg4/bin/awk -v host="$host" '
/NAME:/ {
    gsub(/(^ *NAME: *)|( *$)/, "")
    printf("%s,\"%s\",", host, $0)
    next
}
/VERSION:/ {
    gsub(/(^ *VERSION: *)|( *$)/, "")
    printf("\"%s\",", $0)
    next
}
/BASEDIR:/ {
    gsub(/(^ *BASEDIR: *)|( *$)/, "")
    print
}' >> /tmp/tmp.pkg
sleep 10
cat /tmp/tmp.pkg | while read LINE
do 
   echo "`uname -n` $LINE" >> /tmp/`uname -n`.pk
done

I commented out the host portion as it did not seem to work for me.

Thank you soo much for your help and assistance.

Sorry, I forgot that /bin/sh on Solaris systems is an old Bourne shell that doesn't recognize the $(command) form of command substitution. Please insert the following as the 1st line in the script I gave you:

#!/usr/xpg4/bin/sh

and remove all of the other changes you made.

Aternatively, change the line:

host=$(uname -n)

to:

host=`uname -n`

and remove all of the other changes you made.

I learned how to use UNIX system utilities and libraries by reading the manuals from cover to cover. (Unfortunately, most systems don't have paper manuals anymore, but you can still find the directories that contain the manual pages for your system and use the man utility to read what is available on your system. I would suggest starting with the commands:

man 1 intro
man man
man sh
  and
man awk

When you look at code in The UNIX and Linux Forums and don't understand what it is doing, look up the man page for that utility. (You may notice that utilities on some systems support options that the utilities on Solaris systems do not support and that some utilities on Solaris systems support options that are not supported on other systems. You may also notice that some utilities only appear on Solaris systems and some utilities that are available on other systems are not available on Solaris systems. This is why it is important to always tell us what operating system and shell you're using when you post questions here.)

The modified script with comments is:

#!/usr/xpg4/bin/sh
# Previous line specifies the shell that is to be used to interpret this script.
host=$(uname -n)        # Get system host name.

# Invoke pkginfo and feed the output into awk.  Set the awk variable "host" to
# the same value stored in the shell variable "host".
pkginfo -l | /usr/xpg4/bin/awk -v host="$host" '
/NAME:/ {       # For every line in the input file that contains "NAME:"...
        gsub(/(^ *NAME: *)|( *$)/, "")  # remove leading spaces, "NAME:" and any
                                        # spaces following it, and remove
                                        # trailing spaces from the current input
                                        # line.
        printf("%s,\"%s\",", host, $0)  # Print the host name and the quoted
                                        # NAME: field.  Note that printf() does
                                        # not add a <newline> unless explicitly
                                        # told to do so.
        next    # Skip remaining actions for this line and start processing the
                # next input line.
}
/VERSION:/ {    # Perform similar processing for lines containing "VERSION:"...
        gsub(/(^ *VERSION: *)|( *$)/, "")
        printf("\"%s\",", $0)
        next
}
/BASEDIR:/ {    # Perform similar processing for lines containing "BASEDIR:"...
        gsub(/(^ *BASEDIR: *)|( *$)/, "")
        print   # Note that print() (without arguments) prints the (modified)
                # contents of the current line and adds a trailing <newline>
                # character.
}'

Your modifications worked like a charm. Please mark resolved.

#!/bin/sh
# Previous line specifies the shell that is to be used to interpret this script.
host=`uname -n`        # Get system host name.
# Invoke pkginfo and feed the output into awk.  Set the awk variable "host" to
# the same value stored in the shell variable "host".
pkginfo -l | /usr/xpg4/bin/awk -v host="$host" '
/NAME:/ {       # For every line in the input file that contains "NAME:"...
        gsub(/(^ *NAME: *)|( *$)/, "")  # remove leading spaces, "NAME:" and any
                                        # spaces following it, and remove
                                        # trailing spaces from the current input
                                        # line.
        printf("%s,\"%s\",", host, $0)  # Print the host name and the quoted
                                        # NAME: field.  Note that printf() does
                                        # not add a <newline> unless explicitly
                                        # told to do so.
        next    # Skip remaining actions for this line and start processing the
                # next input line.
}
/VERSION:/ {    # Perform similar processing for lines containing "VERSION:"...
        gsub(/(^ *VERSION: *)|( *$)/, "")
        printf("\"%s\",", $0)
        next
}
/BASEDIR:/ {    # Perform similar processing for lines containing "BASEDIR:"...
        gsub(/(^ *BASEDIR: *)|( *$)/, "")
        print   # Note that print() (without arguments) prints the (modified)
                # contents of the current line and adds a trailing <newline>
                # character.
}'