|
Home > Archive > Unix Shell > February 2007 > Using eval with awk
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Using eval with awk
|
|
| maxshop 2007-02-23, 1:18 pm |
| Environment: AIX 5.2 (ksh)
Hello Group,
I am trying to use eval with awk, but somehow I just cannot get it
right. Maybe some of you can point me in the right direction. Here is
what I am doing inside a script:
#!/usr/bin/ksh
loginname=$1
excl_users="root"
If [[ ! -z $loginname ]]
then
cond1="\$1 == lname &&"
var1="lname=\$loginname"
fi
# My original command looked something like this:
ps -ef | awk '$0 ~ /_oracle/ print {$1,$2,$3,$6}' | egrep -vw
"$excl_users" | sort -u > /tmp/test.log
# I would now like to include $cond1 and $var1 --- So, if $loginname
contains a value, the ps
# command will return processes for that user only that contain
"_oracle". If it does not contain
# a value, then it should return all processes that contain "_oracle".
# I know that the following does not work & that's where I need some
help.
eval 'ps -ef | awk '$cond1 $0 ~ /_oracle/ print {$1,$2,$3,$6}' $var1 |
egrep -vw "$excl_users" | \
sort -u > /tmp/test.log'
Thanks for any suggestions.
S
| |
| Ed Morton 2007-02-23, 1:18 pm |
| maxshop wrote:
> Environment: AIX 5.2 (ksh)
>
> Hello Group,
>
> I am trying to use eval with awk, but somehow I just cannot get it
> right. Maybe some of you can point me in the right direction. Here is
> what I am doing inside a script:
>
> #!/usr/bin/ksh
>
> loginname=$1
> excl_users="root"
>
> If [[ ! -z $loginname ]]
ITYM:
if [ -n "$loginname" ]
> then
> cond1="\$1 == lname &&"
> var1="lname=\$loginname"
> fi
>
> # My original command looked something like this:
> ps -ef | awk '$0 ~ /_oracle/ print {$1,$2,$3,$6}' | egrep -vw
> "$excl_users" | sort -u > /tmp/test.log
>
> # I would now like to include $cond1 and $var1 --- So, if $loginname
> contains a value, the ps
> # command will return processes for that user only that contain
> "_oracle". If it does not contain
> # a value, then it should return all processes that contain "_oracle".
>
> # I know that the following does not work & that's where I need some
> help.
>
> eval 'ps -ef | awk '$cond1 $0 ~ /_oracle/ print {$1,$2,$3,$6}' $var1 |
> egrep -vw "$excl_users" | \
> sort -u > /tmp/test.log'
>
> Thanks for any suggestions.
> S
>
awk is not shell. You cannot access shell variables in awk any more than
you can access shell variables in C. You CAN jump out of awk back into
shell by nesting single quotes, e.g.:
awk 'awk stuff...'shell stuff...'more awk stuff' file
but that's very risky as it leads to bizarre errors and equally bizarre
error messages if the "shell stuff..." contains unexpected text.
You can also initialise an awk variable to the value of a shell
variable. That's the safer, preferred way to do it. See question 24 in
the FAQ (http://home.comcast.net/~j.p.h/cus-faq-2.html#24) for a
discussion on that. The downside for you is that you can't pass the
actual condition (e.g. "==" in "cond1="\$1 == lname") but that's really
messay anyway.
I'd write what you appear to be trying to do with:
if ...
cond1="\$1 == lname &&"
var1="lname=\$loginname"
fi
.... | awk '$cond1 $0 ~ /_oracle/ print {$1,$2,$3,$6}' $var1
as just this:
.... | awk -v lname="$loginname" '/_oracle/ && (!lname || ($1 == lname)){
print $1,$2,$3,$6 }'
Regards,
Ed.
| |
| maxshop 2007-02-23, 1:18 pm |
|
> as just this:
>
> ... | awk -v lname="$loginname" '/_oracle/ && (!lname || ($1 == lname)){
> print $1,$2,$3,$6 }'
>
> Regards,
>
> Ed
Thanks Ed, that worked!
| |
| aryzhov@spasu.net 2007-02-23, 1:18 pm |
| Firstly, the curly bracket in awk print action is in the wrong
position.
Hence the awk syntax error.
Then, you really have to be careful with the quotes and $ signs.
Especially when using a quoted expression inside another one.
Usually, the inside quotes need to be preceded with an escape
character \'
or duplicated.
I also have an irrational feeling that double qoutes " behave more
predictably in nested quote expressions than single quotes '
I suggest to use "eval echo" for debugging.
This one should be slighly closer to what you are trying to achieve:
eval "ps -ef | awk '\"\$cond1\" \$0 ~ /_oracle/ {print \$1,\$2,\$3,\
$6}' \$var1 | egrep -v \"\$excl_users\" | sort -u > /tmp/test.log"
Regards,
Andrei
| |
| Ed Morton 2007-02-23, 1:18 pm |
| maxshop wrote:
>
>
> Thanks Ed, that worked!
>
Good, now on to your second issue:
excl_users="root"
ps -ef | awk '...' | egrep -vw "$excl_users"
You don't need to use awk AND grep since awk can do pattern
matching/exclusion just as easily as grep can. It looks like what you're
trying to do is only produce output for users other than "root", so just
change this:
excl_users="root"
ps -ef | awk -v lname="$loginname" '/_oracle/ && (!lname || ($1 ==
lname)){ print $1,$2,$3,$6 }' | egrep -vw "$excl_users"
to this:
ps -ef | awk -v lname="$loginname" '/_oracle/ && ($1 != "root") &&
(!lname || ($1 == lname)) { print $1,$2,$3,$6 }'
Regards,
Ed.
| |
| maxshop 2007-02-23, 1:18 pm |
| > Good, now on to your second issue:
>
> excl_users="root"
> ps -ef | awk '...' | egrep -vw "$excl_users"
>
> You don't need to use awk AND grep since awk can do pattern
> matching/exclusion just as easily as grep can. It looks like what you're
> trying to do is only produce output for users other than "root", so just
> change this:
>
> excl_users="root"
> ps -ef | awk -v lname="$loginname" '/_oracle/ && (!lname || ($1 ==
> lname)){ print $1,$2,$3,$6 }' | egrep -vw "$excl_users"
>
> to this:
>
> ps -ef | awk -v lname="$loginname" '/_oracle/ && ($1 != "root") &&
> (!lname || ($1 == lname)) { print $1,$2,$3,$6 }'
>
> Regards,
>
> Ed.
Ok, will do it this way.
One other question: Apart from searching for processes that contain
"_oracle", I am also searching for the db name. The db name could
appear anywhere under the CMD column of the ps command & could have
any of the following forms:
xx xxx master xx xxx
xx xxx /data/db/master xx xxx
xx master.db xxx xx xxx
xx xxx /data/db/master.db xx xxx
The "xx xxx" denotes that there are a bunch of parameter/arguments
which could appear anywhere in the CMD column. Is there a way to just
search for processes that contain "master" or "master.db"?
The current command that I have is something like this: I know this
will fail if there is a process out there that would contain
master.prf (for example)
DB_NAME=master
ps -ef | awk '/_oracle/ && $0 ~ db_name {print $1,$2,$3,$6}'
db_name="$DB_NAME"
Thanks,
S
| |
| Ed Morton 2007-02-23, 7:17 pm |
| maxshop wrote:
>
>
> Ok, will do it this way.
>
> One other question: Apart from searching for processes that contain
> "_oracle", I am also searching for the db name. The db name could
> appear anywhere under the CMD column of the ps command & could have
> any of the following forms:
>
> xx xxx master xx xxx
> xx xxx /data/db/master xx xxx
> xx master.db xxx xx xxx
> xx xxx /data/db/master.db xx xxx
>
> The "xx xxx" denotes that there are a bunch of parameter/arguments
> which could appear anywhere in the CMD column. Is there a way to just
> search for processes that contain "master" or "master.db"?
>
> The current command that I have is something like this: I know this
> will fail if there is a process out there that would contain
> master.prf (for example)
>
> DB_NAME=master
> ps -ef | awk '/_oracle/ && $0 ~ db_name {print $1,$2,$3,$6}'
> db_name="$DB_NAME"
DB_NAME="^master(.db)?$"
ps -ef | awk -v db_name="$DB_NAME" '/_oracle/ && $0 ~ db_name {print
$1,$2,$3,$6}'
Using "-v" is a good habit to get into for the reasons specified in the
FAQ I mentioned earlier in the thread.
Regards,
Ed.
| |
| Ed Morton 2007-02-23, 7:17 pm |
| Ed Morton wrote:
> maxshop wrote:
>
>
>
> DB_NAME="^master(.db)?$"
Make that:
DB_NAME="[ /]master(.db)?[ ]"
If a blank character isn't adequate, make it:
DB_NAME="[[:space:]/]master(.db)?[[:space:]]"
> ps -ef | awk -v db_name="$DB_NAME" '/_oracle/ && $0 ~ db_name {print
> $1,$2,$3,$6}'
>
> Using "-v" is a good habit to get into for the reasons specified in the
> FAQ I mentioned earlier in the thread.
>
> Regards,
>
> Ed.
|
|
|
|
|