从两个字符串之间的日志文件中提取行,中间有第三个字符串

Pull lines from log file between two strings with a third string inbetween

我正在寻找一种命令行方式(在 SunOS 上)从日志文件 xml 中提取包含特定字符串的消息。

例如,日志文件可能包含 xml 形式的消息:

<message>
    <body>
        <tags> uniqueId="123456" </tags>
    </body>
</message>

与其他带时间戳的日志行一起。可能有几条 xml 条消息包含相同的 ID,因为同一条记录可能已 运行 多次。

要取出 xmls 目前我有这个 awk 命令:

nawk '[=11=]~s{for(c=NR-b;c<=NR+a;c++)r[c]=1}{q[NR]=[=11=]}END{for(c=1;c<=NR;c++)if(r[c])print q[c]}' b=4 a=15 s="someUniqueId" file

我遇到的问题是这会拉出特定数量的行。然而,xmls 的长度可能会有所不同,我正在努力寻找一种方法来修改它,以便它找到唯一的 ID 并将所有行向上拉到 "<message>",所有行向下直到 "</message>"

这可能适用于完美世界(如果我理解你的问题的话):

$ cat file
<message>
    <body>
        <tags> uniqueId="123455" </tags>
    </body>
</message>
<message>
    <body>
        <tags> uniqueId="123456" </tags>      # the one we want
    </body>
</message>
<message>
    <body>
        <tags> uniqueId="123457" </tags>
    </body>
</message>

awk:

$ awk '
{ 
    b=b ORS [=11=]                            # buffer records
}
/<message>/ {                             
    b=[=11=]                                  # reset buffer
} 
/<\/message>/ && b~/uniqueId="123456"/ {  # if condition met at the end marker
    print b                               # output buffer
}' file

输出:

<message>
    <body>
        <tags> uniqueId="123456" </tags>      # the one we wanted
    </body>
</message>

你也可以试试 Perl,

perl -0777 -ne ' while( m{(<message>(.+?)</message>)}sg ) 
     { $x=; if($x=~/uniqueId="123456"/) { print "\n" }} ' edman.txt

使用来自@James 的输入,

$ cat edman.txt
<message>
    <body>
        <tags> uniqueId="123455" </tags>
    </body>
</message>
<message>
    <body>
        <tags> uniqueId="123456" </tags>      # the one we want
    </body>
</message>
<message>
    <body>
        <tags> uniqueId="123457" </tags>
    </body>
</message>

$ perl -0777 -ne ' while( m{(<message>(.+?)</message>)}sg ) 
    { $x=; if($x=~/uniqueId="123456"/) { print "$x\n" }} ' edman.txt
<message>
    <body>
        <tags> uniqueId="123456" </tags>      # the one we want
    </body>
</message>
$