从两个字符串之间的日志文件中提取行,中间有第三个字符串
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>
$
我正在寻找一种命令行方式(在 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>
$