How to match the pattern specified in a variable in awk?

I want to extract a substring where a specific pattern exists from a pipe-split file, so I used the command below

awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt 

Here, 'REWARD REQ. SERVER HEADERS 'is the template to look for in the file, and print the first 4 parts in a highlighted colon line.

Now I want to send a bash variable to act as a template. so I used the command below, but it does not work.

 awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt 

How can I use -v and -F in the same awk command?

+6
source share
3 answers

The problem here is not related to -F .

The problem is to use /pat/ if you want pat be a variable. If you say /pat/ , awk understands it as the literal "pat", so it will try to match strings containing the string "pat".

If you want to provide a template through a variable, you need to use ~ like this:

  awk -v pat="$pattern" '$0 ~ pat' 

All together, your code should be:

 awk -v pat="$pattern" -F ":" '$0~pat{print $1, $2, $3, $4 }' file # ^^^^^^ 

See an example:

This file:

 $ cat file hello this is a var hello bye 

Let's look at the lines containing "hi":

 $ awk '/hello/' file hello hello bye 

Now try to find the "pat" contained in the variable, as you did:

 $ awk -v pat="hello" '/pat/' file $ # NO MATCHES! 

Now use the expression $0 ~ pat :

 $ awk -v pat="hello" '$0~pat' file hello # WE MATCH! hello bye 

Of course, you can use such expressions to match only one field and say awk -v pat="$pattern" '$2 ~ pat' file , etc.

From GNU Awk User Guide → 3.1 How to use regular expressions :

When a regular expression is enclosed in slashes, such as / foo /, we call it a regular expression constant, just as 5.27 is a numeric constant, and "foo" is a string constant.

And GNU Awk User Guide → 3.6 Using Dynamic Regular Expressions :

The right part of the operator is ~ or ~! should not be a regular expression constant (i.e. a string of characters between a slash). It can be any expression. The expression is evaluated and converted to a string, if necessary; the contents of the string are then used as a regular expression. regexp computed this way is called a dynamic regular expression or computed regular expression:

 BEGIN { digits_regexp = "[[:digit:]]+" } $0 ~ digits_regexp { print } 

This sets digits_regexp to a regular expression that describes one or more digits, and checks if the input record matches this regular expression.

+15
source
 awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt 

You cannot use a variable inside regex // notation (there is no way to distinguish it from pat search); you must indicate that the variable is a regular expression with the ~ (matching) operator.

+4
source

This is kind of a hack, but it makes things a little easier for me.

 cmd="awk '/$pattern/'" eval $cmd 

by creating a string first, you can manipulate it outside of awk

0
source

All Articles