awk handling special chars while capturing text be

2019-06-14 00:50发布

问题:

I have the following line of awk code in my script which searches text between start and end patterns from logs.

Logs look similar to:

[zzzz] Static WEB3
[zzzz] capture me
[zzzz] capture me
[zzzz] capture me
[zzzz] end-pattern

OR could be

[zzzz] Static WEB1 :: WEB2 :: WEB3
[zzzz] capture me
[zzzz] capture me
[zzzz] capture me
[zzzz] end-pattern

Awk script:

awk "/\[zzzz\] Static ${VAR3} / || /${VAR1} :: ${VAR2} :: ${VAR3} /{flag=1;next} /end-pattern:/{flag=0}flag" /tmp/error.log 

I got these errors:

01:18:35 awk: cmd. line:1: /\[zzzz\] Static WEB3 / || /WEB1 :: WEB2 :: WEB3 /{flag=1;next}           /end-pattern:/{flag=0}flag
01:18:35 awk: cmd. line:1:                                          ^ syntax error
01:18:35 awk: cmd. line:1: /\[zzzz\] Static WEB3 / || /WEB1 :: WEB2 :: WEB3 /{flag=1;next}           /end-pattern:/{flag=0}flag
01:18:35 awk: cmd. line:1:                                                                                         ^ syntax error

I don't understand why I get the above syntax errors from awk, while the above code executes perfectly on my local machine (ubuntu 16.04, with bash GNU bash, version 4.3.46(1)-release).

I also tried using \ before : to escape however I get a different issue.

01:18:35 awk: cmd. line:1: /\[zzzz\] Static WEB3 / || /WEB1 \:\: WEB2 \:\: WEB3 /{flag=1;next}           /end-pattern:/{flag=0}flag
01:18:35 awk: cmd. line:1:                                            ^ backslash not last character on line
01:18:35 awk: cmd. line:1: /\[zzzz\] Static WEB3 / || /WEB1 \:\: WEB2 \:\: WEB3 /{flag=1;next}           /end-pattern:/{flag=0}flag
01:18:35 awk: cmd. line:1:                                                                                             ^ syntax error

What am I missing here ?

回答1:

Never use double quotes around the whole of any script (whether it's awk or sed or anything else) as they let shell variables expand to become part of the body of the script and so lead to obscure errors and cryptic error messages (if you're lucky!).

To do what you want with awk you set awk variables to the value of the shell variables and then use the awk variables within the script:

awk -v var1="$VAR1" -v var2="$VAR2" -v var3="$VAR3" '
  $0 ~ ("\[zzzz\] Static " var3 " ") || $0 ~ (var1 " :: " var2 " :: " var3 " ") {flag=1;next}
  /end-pattern:/{flag=0}flag
' /tmp/error.log

I didn't check if the script makes sense or not, just fixed the syntax to use awk variables instead of trying to use shell variables.



标签: bash shell awk sed