I need a solution to awk out an unknown column. I am unable to say '{print $x}' because the location changes. I would like to find a perl or awk solution to this. I do not know either very well but am trying to delve deeper into both.
I am looking for the version of pkg8 in this example. Please keep in mind the location of pkg8 will change depending...
I was able to find a UGLY solution which includes a for loop and if statement. But this is very slow. I am looking at this file on 200 + systems, so the execution does matter.
Here is the entire script for this :
#!/bin/ksh
HOSTNAME=`uname -n`
OS_VER=`uname -r`
PKG=XXXpkg8
CORRECT_VER=5.7.0.10
COLLECT=/tmp/trash
for x in `grep $PKG $COLLECT|awk -F: '{print $2}'`;do
if [ `echo $x|grep "XXXpkg8("` ];then
PKG_VER=`echo $x|grep "XXXpkg8("`
else
continue
fi
done
VER=`echo $PKG_VER|awk -F"(" '{print $2}'|sed -e 's/)//'`
if [[ $VER = $CORRECT_VER ]];then
if [[ $STATUS = NO ]];then
continue
else
STATUS=YES
fi
else
STATUS=NO
MESSAGE="$MESSAGE XXXpkg8:$VER"
fi
echo "$STATUS $MESSAGE"
While I appreciate your post, I am not an expert with awk. I was unable to get your example to work. This is what I tried.
awk '{
for( `grep $PKG $COLLECT|awk -F: '{print $2}'` ) #go through all fields
{
if( XXXpkg8 ){
print field
}
}
}' $COLLECT
I am not sure how this will populate the $VER which is what I am after.
Aigles,
Thanks for the example. I was able to drop the one line in and it worked perfectly. Since I am no expert with sed/awk/perl, I really appreciate you providing an example that I could just drop in. However it turned out to be very slow. Since I will be running this within another for loop (about 200 times), I need it to run faster.
I ran your sed in ./check_pkg and my code was in check_pkg2.
root@smsdr2# time ./check_pkg
YES
real 0m1.737s
user 0m1.500s
sys 0m0.000s
root@smsdr2# time ./check_pkg2
YES
real 0m0.365s
user 0m0.040s
sys 0m0.060s
root@smsdr2# diff check_pkg check_pkg2
8,16c8,15
< #for x in `grep $PKG $COLLECT|awk -F: '{print $2}'`;do
< # if [ `echo $x|grep "XXXpkg8("` ];then
< # PKG_VER=`echo $x|grep "XXXpkg8("`
< # else
< # continue
< # fi
< #done
< #VER=`echo $PKG_VER|awk -F"(" '{print $2}'|sed -e 's/)//'`
< VER=$( sed -n 's/.*'"$PKG"'(\([^)]*\)).*/\1/p' $COLLECT )
---
> for x in `grep $PKG $COLLECT|awk -F: '{print $2}'`;do
> if [ `echo $x|grep "XXXpkg8("` ];then
> PKG_VER=`echo $x|grep "XXXpkg8("`
> else
> continue
> fi
> done
> VER=`echo $PKG_VER|awk -F"(" '{print $2}'|sed -e 's/)//'`
17a17,18
>
>
Why do you need to run it in another loop? Perhaps you could show us the whole code so we can see what to optimize. (I'm thinking maybe you could run the whole loop in sed.)
A little modification to the sed command will increase performances :
VER=$( sed -n "/$PKG/"'s/.*'"$PKG"'(\([^)]*\)).*/\1/p' $COLLECT )
I have tested the three solutions with a file containing 6900 lines (package versions on last line) on my PC (cygwin) and on my AIX box.
The initial version run faster under AIX only (i am very surprise by the difference between Cygwin and AIX results).
The second sed version is the fastest in the two case.
Cygwin times :
---- Initial version ---
YES
real 0m3.140s
user 0m1.047s
sys 0m0.719s
---- sed version -------
YES
real 0m0.406s
user 0m0.215s
sys 0m0.137s
---- sed version 2 -----
YES
real 0m0.360s
user 0m0.231s
sys 0m0.090s
AIX times :
---- Initial version ---
YES
r�el 0m0,14s
util 0m0,00s
sys 0m0,09s
---- sed version -------
YES
r�el 0m1,55s
util 0m1,52s
sys 0m0,03s
---- sed version 2 -----
YES
r�el 0m0,03s
util 0m0,02s
sys 0m0,01s
Works perfectly!! Very quick! This is exactly what I needed -- Thanks!
Now for the really difficult question how does it work?
About all that I can figure out from the man page is -n will "Suppresses the default output". I know the standard sed functions but I can't look at this and tell what it is doing.
$PKG=XXXpkg8
VER=$( sed -n "/XXXpkg8/s/.*XXXpkg8\([^)]*).*/\1/p' )
sed -n Suppress automatic print, output must be explicit (p command)
/XXXpkg8/ Select lines containing XXXpkg8
s/.*XXXpkg8\([^)]*).\).*/ Substitute all the line, memorize version XXXpkg8(version)
/\1/ with memorized version
p Print the result if a substitution have been made
Thanks for providing the breakdown but I still can't translate this to not look for the version in XXXpkg8(version)....
IE how would I do this same task if all I wanted in the output was XXpkg8(version) ....
The parentheses \(...\) select what is being memorized as \1. The parentheses don't affect what is being matched (in this particular case) so you can move them around in the expression. If you have multiple parenthesized expressions, they will be remembered in \1 \2 etc according to the order of the opening parentheses.
The "select" part of the script is actually redundant, since the substitution obviously can only take place on lines where the left-hand side of the substitution expression matches.