2

input file is:

line1 [time-1] abcdef
line2 [time-1] absde1
line3 [time-1] abcdef
line4 [time-1] zzzzzz

this command is working fine:

$ str="abcdef|zzzzzz"
$ awk '!($0~/('"$str"')$/)' test_input
line2 [time-1] absde1

following command fails:

$ str="[time-1] abcdef|[time-1] zzzzzz"
$ echo "${str}"
[time-1] abcdef|[time-1] zzzzzz
$ awk '!($0~/('"$str"')$/)' test_input
awk: fatal: Invalid range end: /([time-1] abcdef|[time-1] zzzzzz)$/
$

Is it possible to pass variable with such string to awk too?

anubhava
  • 761,203
  • 64
  • 569
  • 643
Chris
  • 939
  • 2
  • 11
  • 22
  • 1
    See: https://stackoverflow.com/q/42131314/3776858 – Cyrus Jun 19 '20 at 19:10
  • 1
    @Chris if `[time-1] abcdefgh` existed in your input file, should it get printed or not when `str="[time-1] abcdef"`? Can `str` contain any other regexp metachars like `.`, `?`, `{`, `+`, or `*`? – Ed Morton Jun 19 '20 at 20:28
  • you're trying to do part literal part regex match. You have to choose one or the other. – karakfa Jun 19 '20 at 20:46

2 Answers2

1

One more awk:

awk -v str="$str" 'BEGIN {
   n = split(str, a, "|")
}
{
   for (i=1; i<=n; i++)
      if (index($0, a[i]))
         next
   print
}' file

line2 [time-1] absde1

Reason why you cannot just use $str as regex is that you have regex meta characters such as [, ] etc.

anubhava
  • 761,203
  • 64
  • 569
  • 643
0

You just have to escape the square brackets

$ str="\[time-1\] abcdef|\[time-1\] zzzzzz"
$ awk '!($0~/('"$str"')$/)' test_input
line2 [time-1] absde1

--- Edit --------------------------

To create the str variable with escaped characters

str="[time-1] abcdef|[time-1] zzzzzz" | sed -e 's/[]\/$*.^[]/\\&/g'

This way, the pipe-separated list can be an automatically generated list.