Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match a pattern given in a variable in awk?

I want to extract a substring where certain pattern exist from pipe separated file, thus I used below command,

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

Here, 'REWARD REQ. SERVER HEADERS' is a pattern which is to be searched in the file, and print its first 4 parts on a colon separated line.

Now, I want to send bash variable to act as a pattern. thus I used below command, but it's not working.

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

How can I use -v and -F in a single awk command?

like image 716
Chintamani Manjare Avatar asked Sep 08 '16 06:09

Chintamani Manjare


People also ask

Can we search a pattern using awk?

Any awk expression is valid as an awk pattern. The pattern matches if the expression's value is nonzero (if a number) or non-null (if a string). The expression is reevaluated each time the rule is tested against a new input record.

How do you reference a variable in awk?

'$' symbol is used with a shell variable name to read the value. The second command reads the variable, $myval with a single quote(') and the third command reads the variable $myvar with double quote(“) in the `awk` statement.

Can you use regex in awk?

In awk, regular expressions (regex) allow for dynamic and complex pattern definitions. You're not limited to searching for simple strings but also patterns within patterns.

Which operator is used to match a REGK in awk?

The two operators, `~' and `!~' , perform regular expression comparisons. Expressions using these operators can be used as patterns or in if , while , for , and do statements. This is true if the expression exp (taken as a character string) is not matched by regexp .


1 Answers

If you want to provide the pattern through a variable, you need to use ~ to match against it:

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

In your case, the problem does not have to do with -F.

The problem is the usage of /pat/ when you want pat to be a variable. If you say /pat/, awk understands it as a literal "pat", so it will try to match those lines containing the string "pat".

All together, your code should be:

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

See an example:

Given this file:

$ cat file hello this is a var hello bye 

Let's look for lines containing "hello":

$ awk '/hello/' file hello hello bye 

Let's now try looking for "pat", contained in a variable, the way you were doing it:

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

Let's now use the $0 ~ pat expression:

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

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

From GNU Awk User's Guide → 3.1 How to Use Regular Expressions:

When a regexp is enclosed in slashes, such as /foo/, we call it a regexp constant, much like 5.27 is a numeric constant and "foo" is a string constant.

And GNU Awk User's Guide → 3.6 Using Dynamic Regexps:

The righthand side of a ‘~’ or ‘!~’ operator need not be a regexp constant (i.e., a string of characters between slashes). It may be any expression. The expression is evaluated and converted to a string if necessary; the contents of the string are then used as the regexp. A regexp computed in this way is called a dynamic regexp or a computed regexp:

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

This sets digits_regexp to a regexp that describes one or more digits, and tests whether the input record matches this regexp.

like image 60
fedorqui 'SO stop harming' Avatar answered Sep 25 '22 08:09

fedorqui 'SO stop harming'