For Programmers: Free Programming Magazines  


Home > Archive > AWK > July 2006 > variable in regexp









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 variable in regexp
joe nedumgottil

2006-07-21, 6:56 pm

Hi,

I'm trying to create a script to read values from an ini file. Here's
the file format:

[profile_group1]
profile_setting1=profile_value2
profile_setting2=profile_value2
....
[profile_group2]
profile_setting3=profile_value3
....

Here's my awk script:

BEGIN {section=0;}

/\[.*\]/ {if ($1 ~ /\[profile_group\]/)
{section=1;}
else {section=0;}
}

/profile_setting/ {if (section==1) {print;}

Here's how I call it:

awk -f getprofilestring.awk profile_group=TestGroup
profile_setting=TestSetting myTestFile

Running this command line never outputs the correct line. However, if
I change my awk script, and hardcode "TestGroup" and "TestSetting" into
it, the script works fine. Why won't my variable substitution work?

I am running on Solaris 9.

Thanks in advance,
Joe

Xicheng Jia

2006-07-21, 6:56 pm

joe nedumgottil wrote:
> Hi,
>
> I'm trying to create a script to read values from an ini file. Here's
> the file format:
>
> [profile_group1]
> profile_setting1=profile_value2
> profile_setting2=profile_value2
> ...
> [profile_group2]
> profile_setting3=profile_value3
> ...
>
> Here's my awk script:
>
> BEGIN {section=0;}
>
> /\[.*\]/ {if ($1 ~ /\[profile_group\]/)
> {section=1;}
> else {section=0;}
> }
>
> /profile_setting/ {if (section==1) {print;}


/\[.*\]/ {if ($1 ~ "\["profile_group"\]")
{section=1;}
else {section=0;}
}
$0 ~ profile_setting {if (section==1) {print;}

> Here's how I call it:
>
> awk -f getprofilestring.awk profile_group=TestGroup
> profile_setting=TestSetting myTestFile


awk -f getprofilestring.awk -v profile_group="TestGroup" -v
profile_setting="TestSetting" myTestFile

you may need to use -v option and quote the assigned values
(untested)

Xicheng

Ed Morton

2006-07-30, 6:56 pm

joe nedumgottil wrote:
> Hi,
>
> I'm trying to create a script to read values from an ini file. Here's
> the file format:
>
> [profile_group1]
> profile_setting1=profile_value2
> profile_setting2=profile_value2
> ...
> [profile_group2]
> profile_setting3=profile_value3
> ...
>
> Here's my awk script:
>
> BEGIN {section=0;}


a) You don't need to init this variable, all variables take the value
zero or null before their first use.
b) Given that, you don't need a BEGIN section.
c) You don't need semi-colons on the end of each line.

> /\[.*\]/ {if ($1 ~ /\[profile_group\]/)
> {section=1;}
> else {section=0;}
> }
>
> /profile_setting/ {if (section==1) {print;}
>
> Here's how I call it:
>
> awk -f getprofilestring.awk profile_group=TestGroup
> profile_setting=TestSetting myTestFile
>
> Running this command line never outputs the correct line. However, if
> I change my awk script, and hardcode "TestGroup" and "TestSetting" into
> it, the script works fine. Why won't my variable substitution work?


/profile_setting/ tells awk to look for the RE "profile_setting". For
example, to look for a stringh matching the RE "abc", you'd do:

awk '/abc/' file

The equivalent using a variable to hold the RE pattern would be:

awk -v pat="abc" '$0 ~ pat' file

So, what you seem to want to do with this final line:

/profile_setting/ {if (section==1) {print;}

is:

$0 ~ profile_setting {if (section==1) {print;}

Now, there's various other tweaks your script could use. Regardless of
whether or not it works, the equivalent of your above script in more
awk-ish syntax would be just these 2 lines (only specifying a condition
for the second line invokes the default action of printing $0):

/\[.*\]/ {section = ($1 ~ /\[profile_group\]/ ? 1 : 0)}
section && /profile_setting/

and the fixed version using variables to find every specified section
within every specified group would be:

/\[.*\]/ {section = ($0 == "[" profile_group "]" ? 1 : 0)}
section && $0 ~ profile_setting

Now, I THINK you'd want to be more accurate in matching the pattern of
the profile setting only in the correct part of the record (presumably
before the "="), and I THINK you'd really only want to print the
profile_value rather than the whole record, so then what I'd REALLY do
is this:

/\[.*\]/ {section = ($0 == "[" profile_group "]" ? 1 : 0)}
section && $1 == profile_setting { print $2 }

and then call it as (note the -F= to set FS):

awk -F= -v profile_group=TestGroup -v profile_setting=TestSetting -f
getprofilestring.awk myTestFile

Regards,

Ed.
Ed Morton

2006-07-30, 6:56 pm

Xicheng Jia wrote:

> joe nedumgottil wrote:
>
>
>
> /\[.*\]/ {if ($1 ~ "\["profile_group"\]")


Not quite:

$ echo "[abc]" | awk -v x=b '$0 ~ "\[" x "\]"'
awk: warning: escape sequence `\[' treated as plain `['
awk: warning: escape sequence `\]' treated as plain `]'
[abc]

You'd need to escape the backslashes:

$ echo "[abc]" | awk -v x=b '$0 ~ "\\[" x "\\]"'
$ echo "[abc]" | awk -v x=abc '$0 ~ "\\[" x "\\]"'
[abc]

but I don't get the impression the OP really wants an RE comparison
here, so I think just using an equality test would be better:

$ echo "[abc]" | awk -v x=b '$0 == "[" x "]"'
$ echo "[abc]" | awk -v x=abc '$0 == "[" x "]"'
[abc]

Regards,

Ed.

> {section=1;}
> else {section=0;}
> }
> $0 ~ profile_setting {if (section==1) {print;}
>
>
>
>
> awk -f getprofilestring.awk -v profile_group="TestGroup" -v
> profile_setting="TestSetting" myTestFile
>
> you may need to use -v option and quote the assigned values
> (untested)
>
> Xicheng
>

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com