1

I have a text file like this:

File1   [test]
File1   sgfg
File1   fdgsfg
File1   [rsyslog]
File1   moredata
File1   MAX_EVENTS = 256
File1   fgsfg
File1   [other]
File1   Not this
File2   [syslog]
File2   extra
File2   MAX_EVENTS = 12

With awk I would like to match field $2 when it contains [syslog]

Example this works

awk '$2~/\[syslog\]/' file

But I like to define field in advance using var.

Not working

awk -v var="[syslog]" '$2~var' file
awk -v var="\[syslog\]" '$2~var' file
awk -v var="syslog" '{test="["var"]"} $2~test' file

This works since both sub needs to be true as well as the text match, but complicated :)

awk -v var="syslog" 'sub(/^\[/,"",$2) && sub(/\]/,"",$2) && $2==var' file
Jotne
  • 40,548
  • 12
  • 51
  • 55

3 Answers3

1

Working cases:

$ awk -v var='[syslog]' 'index($2, var)' file
File2   [syslog]
$ awk -v var='syslog' '$2~"\\[" var "\\]"' file
File2   [syslog]
$ awk -v var='[[]syslog[]]' '$2~var' file
File2   [syslog]

Basically take care of the escaping, or don't use regex matching.

As Ed kindly mentioned in the comment, ] alone does not need to be escaped:

awk -v var='syslog' '$2~"\\[" var "]"' file
awk -v var='[[]syslog]' '$2~var' file
Til
  • 5,150
  • 13
  • 26
  • 34
1

You didn't say if you wanted a full or partial match or if you wanted a string or regexp match so here's some options:

Full string match:

awk -v var='[syslog]' '$2 == var' file

Partial string match:

awk -v var='[syslog]' 'index($2,var)' file

Full regexp match:

awk -v var='[[]syslog]' '$2 ~ "^"var"$"' file

Partial regexp match:

awk -v var='[[]syslog]' '$2 ~ var' file

There are of course, many other ways to do that too including escaping regexp metachars within the awk script to make them literal, specifying the string between [...] in the var then adding them in the awk script, matching just at the start or end of the field, etc.

See How do I find the text that matches a pattern? for more info on the different kinds of matching and Is it possible to escape regex metacharacters reliably with sed (applies to awk too) for how to escape regexp metachars to make them be treated as literal.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

How about something like this?

awk -v var="[syslog]" '$2 == var' my_file

A bit of explanation. If you don't need regular expression matching you can just use == operator which compares strings literally.

Your "Not working" examples weren't working because:

  1. The regular expression is not correct. It matches a single character, any of s,y,l,o,g.
  2. Escaping is not correct, this would have worked var="\\\\[syslog\\\\]". But awk should have warned you about this with the message awk: warning: escape sequence '\[' treated as plain '['.
  3. Not sure, honestly.
Discussian
  • 492
  • 3
  • 10
  • Thanks, this works, but what if I would like to match it on regex, can it be done? Example, some time I like to get all fields in square brackets, then this will not match `.*` for all. – Jotne Aug 09 '21 at 10:14
  • I edited my answer a bit, after looking at your examples more closely. If you want to use regular expressions - the only way is dealing with escaping which can be a pain. – Discussian Aug 09 '21 at 10:34