awk模式可以匹配多行吗?

And*_*lez 20 linux awk

我有一些复杂的日志文件,我需要编写一些工具来处理它们.我一直在玩awk,但我不确定awk是否适合这个.

我的日志文件是OSPF协议解码的打印输出,其中包含各种协议pkts的文本日志及其内容,以及用其值标识的各种协议字段.我想处理这些文件并只打印出与特定pkts相关的日志的某些行.每个pkt日志可以包含该pkt条目的不同行数.

awk似乎能够处理与模式匹配的单行.我可以找到所需的pkt然后我需要匹配后面的行中的模式,以确定它是否是我想要打印的pkt.

另一种看待这种情况的方法是,我希望在日志文件中隔离几行,并根据几行上的模式匹配打印出那些特定pkt细节的行.

由于awk似乎是基于行的,我不确定这是否是最好的工具.

如果awk可以做到这一点,怎么做?如果没有,有关于使用哪种工具的建议?

Dig*_*oss 19

Awk可以轻松检测模式的多行组合,但您需要在代码中创建所谓的状态机以识别序列.

考虑这个输入:

how
second half #1
now
first half
second half #2
brown
second half #3
cow
Run Code Online (Sandbox Code Playgroud)

如您所见,很容易识别单个模式.现在,我们可以写识别的awk程序下半场只有当它直接前面有一个上半年线.(使用更复杂的状态机,您可以检测到任意序列的模式.)

/second half/ {
  if(lastLine == "first half") {
    print
  }
}

{ lastLine = $0 }
Run Code Online (Sandbox Code Playgroud)

如果你运行这个,你会看到:

second half #2
Run Code Online (Sandbox Code Playgroud)

现在,这个例子非常简单,只是一个状态机.有趣的状态仅持续if语句的持续时间,前一状态是隐式的,具体取决于lastLine的值.在更规范的状态机中,您将保留显式状态变量,并根据现有状态和当前输入从状态到状态转换.但是你可能不需要那么多的控制机制.


Vaz*_*Vaz 10

Awk真的是基于记录的.默认情况下,它将一行视为记录,但您可以使用RS(记录分隔符)变量对其进行更改.

解决这个问题的一种方法是使用sed进行第一次传递(如果您愿意,也可以使用awk执行此操作),使用不同的字符(如表单提要)分隔记录.然后你可以写你的awk脚本,它将把这组行视为一个记录.

例如,如果这是您的数据:

animal 0
name: joe
type: dog
animal 1
name: bill
type: cat
animal 2
name: ed
type: cat
Run Code Online (Sandbox Code Playgroud)

要使用换页符分隔记录:

$ cat data | sed $'s|^\(animal.*\)|\f\\1|'
Run Code Online (Sandbox Code Playgroud)

现在我们将把它传递给awk.以下是有条件地打印记录的示例:

$ cat data | sed $'s|^\(animal.*\)|\f\\1|' | awk '
      BEGIN { RS="\f" }                                     
      /type: cat/ { print }'
Run Code Online (Sandbox Code Playgroud)

输出:

animal 1
name: bill
type: cat

animal 2
name: ed
type: cat
Run Code Online (Sandbox Code Playgroud)

编辑:作为奖励,这里是如何使用awk-ward ruby​​(-014表示使用换页符(八进制代码014)作为记录分隔符):

$ cat data | sed $'s|^\(animal.*\)|\f\\1|' |
      ruby -014 -ne 'print if /type: cat/'
Run Code Online (Sandbox Code Playgroud)


Cle*_*oom 6

awk能够从开始模式处理到结束模式

/start-pattern/,/end-pattern/ {
  print
}
Run Code Online (Sandbox Code Playgroud)

我一直在寻找如何搭配

 * Implements hook_entity_info_alter().
 */
function file_test_entity_type_alter(&$entity_types) {
Run Code Online (Sandbox Code Playgroud)

如此创造

/\* Implements hook_/,/function / {
  print
}
Run Code Online (Sandbox Code Playgroud)

我需要哪些内容。一个更复杂的示例是跳过线条并擦掉非空间部分。注意awk是一个记录(行)和单词(由空格分割)工具。

# start,end pattern match using comma
/ \* Implements hook_(.*?)\./,/function (.\S*?)/ {
  # skip PHP multi line comment end
  $0 ~ / \*\// skip

  # Only print 3rd word
  if ($0 ~ /Implements/) {
    hook=$3
    # scrub of opening parenthesis and following.
    sub(/\(.*$/, "", hook)
    print hook
  }

  # Only print function name without parenthesis
  if ($0 ~ /function/) {
    name=$2

    # scrub of opening parenthesis and following.
    sub(/\(.*$/, "", name)

    print name
    print ""
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这也会有所帮助。

另请参见ftp://ftp.gnu.org/old-gnu/Manuals/gawk-3.0.3/html_chapter/gawk_toc.html