如果在括号内包含特定单词AND,则提取多行输出

时间:2019-06-29 09:37:22

标签: perl awk grep

我有这样的输入:

Jun 29 16:46:13 iPhone SomeThing[79987] <Notice>: [AppName] file.x:115 DEBUG: ClassNumberOne viewControllers: (
    "<UINavigationController: 0x105031a00>",
    "<UINavigationController: 0x10505ba00>",
    "<UINavigationController: 0x10486fe00>",
    "<UINavigationController: 0x105052600>",
    "<UINavigationController: 0x105065c00>"
)
Jun 29 16:46:13 iPhone SomeThing[79987] <Notice>: [AppName] file.x:151 DEBUG: ClassNumberTwo ARG2 2

这里有两种情况要匹配,一种是多行,另一种是单行。条件是它必须具有DEBUG:关键字。对于多行,如果该行具有关键字和和(,则它应匹配到)的末尾。每行由换行符分隔。我不知道这个。目前,我正在使用简单的grep DEBUG:,仅此而已。但是对于多线方案,除了第一个方案之外,所有内容都丢失了。而且我对perl不熟悉,知道吗?预先感谢!

请注意,我在iOS上(越狱),因此其他工具可能会受到限制。

编辑:

预期的输出将是符合条件的整行,与上面显示的输入示例相同。实际输入的其他几行没有关键字DEBUG:,因此将被忽略。

2 个答案:

答案 0 :(得分:2)

在每个UNIX机器上的任何外壳中都有任何awk:

$ awk 'f; /\)/{f=0} /DEBUG:/{print; f=/\(/}' file
Jun 29 16:46:13 iPhone SomeThing[79987] <Notice>: [AppName] file.x:115 DEBUG: ClassNumberOne viewControllers: (
    "<UINavigationController: 0x105031a00>",
    "<UINavigationController: 0x10505ba00>",
    "<UINavigationController: 0x10486fe00>",
    "<UINavigationController: 0x105052600>",
    "<UINavigationController: 0x105065c00>"
)
Jun 29 16:46:13 iPhone SomeThing[79987] <Notice>: [AppName] file.x:151 DEBUG: ClassNumberTwo ARG2 2

说明:

awk '       # WHILE read line DO 
f;          #    IF the flag `f` is set THEN print the current line ENDIF
/\)/{f=0}   #    IF the current line contains `)` THEN clear the flag ENDIF
/DEBUG:/ {  #    IF the current line contains `DEBUG:` THEN
    print;  #        print the line
    f=/\(/  #        set the flag `f` to 1 if the line contains `(`, 0 otherwise
}           #    ENDIF
' file      # ENDWHILE

答案 1 :(得分:1)

以下是在Perl中使用Regexp的示例(但是应该由Regexp::Grammars之类的解析器来更精确地处理):

use feature qw(say);
use strict;
use warnings;

my $data = do { local $/; <> };
my @lines = $data 
  =~ /
         ^( (?:(?!$).)* DEBUG:
             (?: 
                 (?: [^(]*? $ ) 
              | 
                 (?: (?:(?!$).)* \( [^)]* \) .*? $ )
             )
         )/gmsx;

say for @lines;