3

I'm using AWK for multiline matching with patterns. Example:

awk '/"ip": /,/"id": /'

I would like to pass an argument to AWK when I know the ip, so that it would return the lines that include the specified IP. Example:

awk '/"ip": "$IP"/,/"id": /'

What would be a way to do it?

I have tried:

awk '/"ip": "$IP"/,/"id": /'
awk '/"ip": "${IP}"/,/"id": /'
awk "/\"ip\": \"$IP\"/,/\"id'\": /"

I was wondering how to use this approach with patterns:

var="hello"; awk -v a="$var"

Thanks.


ANSWER

  • accepted and can be found below.
  • Additional details for anyone interested on how to make the matching more precise (using the variable + a string pattern). Take note that you can't wrap the variable you are using in the pattern with double quotes, it will not work even if the quotes are escapted:

    cat l.txt | awk '$0 ~ "\"ip\": \"103.6.181.43", $0 ~ "\"id\": \""'              ===> works
    cat l.txt | awk -v ipvar=103.6.181.43 '$0 ~ ipvar, $0 ~ "\"id\": \""'           ===> works
    cat l.txt | awk -v ipvar=103.6.181.43 '$0 ~ "\"ip\": \"ipvar", $0 ~ "\"id\": \""' ===> does not work
    cat l.txt | awk -v ipvar=103.6.181.43 '$0 ~ "\"ip\": \""ipvar, $0 ~ "\"id\": \""' ===> works
    

Finally, you can wrap / surround the parameter used in qoutes. Compare:

awk -v ipvar=103.6.181.43 '$0 ~ "\"ip\": \"ipvar\"", $0 ~ "\"id\": \""'  ===> will not work
awk -v ipvar=103.6.181.43 '$0 ~ "\"ip\": \""ipvar"\"", $0 ~ "\"id\": \""' ===> will work and is equivalent.
Mindaugas Bernatavičius
  • 3,757
  • 4
  • 31
  • 58

2 Answers2

2

Do not add the variable within the / /, because what goes there is a regular expression.

Instead, do use $0 ~ pattern, which gives you more freedom. After all,

/pattern1/,/pattern2

Is the same as

$0 ~ pattern1, $0 ~ pattern2

So you can use -v to provide the value and say:

awk -v var="$bash_variable" '$0~"ip: " var,$0 ~ "id: " var'
#                            ^^^^^^^^^^^^^
#                                          ^^^^^^^^^^^^^^^
#                               start           end

Test

$ cat a
hello
ip: 23
bye
and this is
id: 23
hehe
done
$ awk -v var=23 '$0~"ip: " var,/id: /' a
ip: 23
bye
and this is
id: 23
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 1
    Thanks, will also add some more points in the OP for reference to anyone who is lost and stumbles upon the question :) – Mindaugas Bernatavičius Apr 14 '16 at 16:23
  • @MindaugasBernatavičius nice to read it worked to you. I kept my answer very simple. I guess your final solution is a bit more cumbersome because of all these double quotes that need to be escaped. Good thing you show the final version for future readers! – fedorqui Apr 15 '16 at 08:00
1

You're trying to expand a variable inside single quotes. Single quotes (') cause everything between them to be taken literally by bash. Try to use double-quotes instead, and see Quotes.

Regarding your question about awk assignments, here's an exapmle:

awk -v foo="bar" 'foo ~ $0' <<< $'foo\nbar\nbaz'

Output: bar.

Rany Albeg Wein
  • 3,304
  • 3
  • 16
  • 26