dig_123
dig_123

Reputation: 2378

pass bash regex pattern as a part of bigger regex pattern in awk

I am trying to do this in my script:

 CONTEXT_PAT1="\[[gG][lL][oO][bB][aA][lL]\]"

 awk -v pat1="$CONTEXT_PAT1" 'f;/^[:space:]*pat1[:space:]*$/{f=1}' ${CONFIG_FL}

When I run it in debug mode, I see this happening:

 ++ awk -v 'pat1=\[[gG][lL][oO][bB][aA][lL]\]' 'f;/^[:space:]*pat1[:space:]*$/{f=1}

Expected is:

 ++ awk -v 'pat1=\[[gG][lL][oO][bB][aA][lL]\]' 'f;/^[:space:]\[[gG][lL][oO][bB][aA][lL]\][:space:]*$/{f=1}

How can I achieve this ? I have gone through some articles here in stackoverflow

https://unix.stackexchange.com/questions/120788/pass-shell-variable-as-a-pattern-to-awk?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

But this is when you use the regex as it is to awk, but not consider it part of a bigger regex.

How to achieve this ?

Upvotes: 3

Views: 84

Answers (2)

marcolz
marcolz

Reputation: 2970

Edit: To get the output that you expect from your sh -x trace, read this answer. To create proper awk code, read @ghoti's answer.

$ expansion does not happen inside single quotes ('), but does in double quotes ". Try:

CONTEXT_PAT1="\[[gG][lL][oO][bB][aA][lL]\]"

awk 'f;/^[:space:]'"${CONTEXT_PAT1}"'[:space:]*$/{f=1}' "${CONFIG_FL}"

The shell will not expand *pat1 for you. Assuming that what you mean by "debug mode" is sh -x

Upvotes: -1

ghoti
ghoti

Reputation: 46876

You CAN in fact match against a variable or a function. It's only the implicit shorthand where a RE is intended to match the whole line where there is no mechanism to embed a variable in a larger RE. So you might want to be EXplicit, and use the RE operator, ~.

For your example, I'd go with something like this:

$ pat1="[[][gG][lL][oO][bB][aA][lL][]]"
$ awk -v pat1="$pat1" 'BEGIN{re="^[[:space:]]*" pat1 "[[:space:]]*$"} f; $0~re{f=1}' file.cfg

Or even,

$ awk -v pat1="$pat1" 'f; $0~sprintf("^[[:space:]]*%s[[:space:]]*$",pat1) {f=1}' file.cfg

I might even simplify the use of this thing further by saving you the hassle of passing in a case insensitive regex:

$ pat1="global"
$ awk -v pat1="$pat1" 'f; tolower($0) ~ sprintf("^[[:space:]]*[[]%s[]][[:space:]]*$",tolower(pat1)) {f=1}' file.cfg

Upvotes: 4

Related Questions