在捕获两种模式之间的文本时,awk处理特殊字符 [英] awk handling special chars while capturing text between two patterns

查看:98
本文介绍了在捕获两种模式之间的文本时,awk处理特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的脚本中包含以下awk代码行,可从日志中搜索开始模式和结束模式之间的文本.

日志看起来类似于:

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

或可能是

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

Awk脚本:

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

我遇到了这些错误:

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

我不明白为什么要从awk中获得上述syntax errors,而以上代码在我的本地计算机上完美执行(ubuntu 16.04,带有bash GNU bash,版本4.3.46(1)-发行版)./p>

我也尝试在:之前使用\进行转义,但是我遇到了另一个问题.

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

我在这里想念什么?

解决方案

切勿在所有脚本(无论是awk还是sed或其他任何东西)的整体上使用双引号,因为它们会让shell变量扩展成为主体的一部分.脚本,因此会导致晦涩的错误和神秘的错误消息(如果您很幸运!).

要使用awk进行所需的操作,请将awk变量设置为shell变量的值,然后在脚本中使用awk变量:

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

我没有检查脚本是否有意义,只是修复了使用awk变量而不是尝试使用shell变量的语法.

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 ?

解决方案

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.

这篇关于在捕获两种模式之间的文本时,awk处理特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆