Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在Linux上从日志文件中提取XML块_Php_Regex_Linux_Perl_Command Line - Fatal编程技术网

Php 如何在Linux上从日志文件中提取XML块

Php 如何在Linux上从日志文件中提取XML块,php,regex,linux,perl,command-line,Php,Regex,Linux,Perl,Command Line,我有一个如下所示的日志文件: 2010-05-12 12:23:45 Some sort of log entry 2010-05-12 01:45:12 Request XML: <RootTag> <Element>Value</Element> <Element>Another Value</Element> </RootTag> 2010-05-12 01:45:32 Response XML: <Respon

我有一个如下所示的日志文件:

2010-05-12 12:23:45 Some sort of log entry
2010-05-12 01:45:12 Request XML: <RootTag>
<Element>Value</Element>
<Element>Another Value</Element>
</RootTag>
2010-05-12 01:45:32 Response XML: <ResponseRoot>
<Element>Value</Element>
</ResponseRoot>
2010-05-12 01:45:49 Another log entry
2010-05-12 12:23:45某种日志条目
2010-05-12 01:45:12请求XML:
价值
另一个价值
2010-05-12 01:45:32响应XML:
价值
2010-05-12 01:45:49另一个日志条目
我想做的是提取请求和响应XML(并最终将它们转储到它们自己的单个文件中)。我有一个使用egrep的类似解析器,但是XML都在一行上,而不是像上面那样的多行

日志文件也有点大,达到500-600兆/日志。我会通过PHP脚本读取较小的日志,并使用正则表达式匹配,但如此大的文件所需的内存量很可能会杀死脚本


有没有一种简单的方法可以使用Linux机器上的内置工具(本例中是CentOS)提取多行代码,还是我必须咬紧牙关,使用Perl或PHP读取整个文件来提取它?

你的问题表明你的想法不对;如果有一种方法可以用一种语言实现你的要求(有)。。。然后你可以用任何语言来做


没有理由将整个日志读取到内存中。你只要逐行阅读并提取你想要的信息。你只需要保持一个状态,知道你在哪里(不在标签、根标签内、响应区内等等),然后按照你的意愿处理数据。

你的问题意味着你没有正确思考;如果有一种方法可以用一种语言实现你的要求(有)。。。然后你可以用任何语言来做

# Example usage:
# perl script.pl data.xml RootTag > RootTag.xml

use strict;
use warnings;

my $tag = pop;

while (<>){
    if ( s/.*(<$tag>)/$1/ .. s/(<(\/)$tag>).*/$1/ ){
        print;
        last if $2;
    }
}
没有理由将整个日志读取到内存中。你只要逐行阅读并提取你想要的信息。您只需保持您所在位置的状态(不在标记中、在RootTag内部、在ResponseRoot内部等),并根据需要处理数据。

#示例用法:
# Example usage:
# perl script.pl data.xml RootTag > RootTag.xml

use strict;
use warnings;

my $tag = pop;

while (<>){
    if ( s/.*(<$tag>)/$1/ .. s/(<(\/)$tag>).*/$1/ ){
        print;
        last if $2;
    }
}
#perl script.pl data.xml RootTag>RootTag.xml 严格使用; 使用警告; 我的$tag=pop; 而(){ 如果(s/*()/$1/.s/().*/$1/){ 打印 最后,如果2美元; } }
有关使用示例的详细信息,请参阅文档 #perl script.pl data.xml RootTag>RootTag.xml 严格使用; 使用警告; 我的$tag=pop; 而(){ 如果(s/*()/$1/.s/().*/$1/){ 打印 最后,如果2美元; } }
有关的详细信息,请参阅文档。

听起来像是
sed
的工作(我很想说SuperSed;-)

是一个正则表达式条件,它匹配任何一行,该行包含
——基本上是带有XML标记的任何行。相关操作是
H
,它将行附加到“保持缓冲区”。另一个条件是

/\(Request\|Response\) XML/
当然,这是一个regexp,它匹配
请求
响应
,后跟空格,然后是
XML
。相应的动作是

{s/^.*</</;x;p}
匹配输入的结尾,然后再次将保持缓冲区的内容交换到“打印缓冲区”中,然后打印它

您可以根据需要更改命令,例如,如果需要对不同的记录进行分隔,这将在它们之间放置一条空行:

sed -n '/^<.\+>/H; /\(Request\|Response\) XML/{s/^.*</\n</;x;p}; ${x;p}' xmllog

sed-n'/^/H/\(Request\| Response\)XML/{s/^.*听起来像是sed的工作(我很想说SuperSed;-)

是一个正则表达式条件,它匹配任何一行,该行包含
——基本上是带有XML标记的任何行。关联操作是
H
,它将该行附加到“保持缓冲区”。另一个条件是

/\(Request\|Response\) XML/
当然,这是一个regexp,它匹配
请求
响应
,后跟空格,然后是
XML

{s/^.*</</;x;p}
匹配输入的结尾,然后再次将保持缓冲区的内容交换到“打印缓冲区”中,然后打印它

您可以根据需要更改命令,例如,如果需要对不同的记录进行分隔,这将在它们之间放置一条空行:

sed -n '/^<.\+>/H; /\(Request\|Response\) XML/{s/^.*</\n</;x;p}; ${x;p}' xmllog

sed-n'/^/H;/\(请求\响应\)XML/{s/^.*没有理由不能用PHP来完成。当然,你不能将整个日志加载到内存中,你必须以流式方式扫描它。没有理由不能用PHP来完成。当然,你不能将整个日志加载到内存中,你必须以流式方式扫描它。我不是说我不想用合适的语言来完成,我只知道有时候你可以用内置工具拼凑出一些好东西:)如果这不可能,那么我将编写一些东西。我不是说我不想用合适的语言来编写,我只是知道有时候你可以用内置工具拼凑出一些好东西:)如果这不可能,那么我将编写一些东西漂亮、整洁、简单。我扩展了它,以便在有多个XML集的情况下将每个报告转储到一个文件中,但这已经足够让我开始了。在您的情况下,您可能需要编写$tag=qr/(?:RootTag | ResponseRoot)/;qr创建一个regexp和(?:…)这意味着括号没有捕获匹配项,也不是必需的,但使用它们可能是一种良好的做法。此外,这里的假设是,这两个标记仅用作各自XML片段的根(这很可能).Nice、neat和simple。我对其进行了扩展,以便在有多个XML集的情况下将每个报表转储到一个文件中,但这已经足够让我开始了。在您的情况下,您可能需要编写$tag=qr/(?:RootTag | ResponseRoot)/;qr创建一个regexp和(?:…)这意味着括号没有捕获匹配项,也不是必需的,但使用它们可能是一种良好的做法。此外,这里的假设是,这两个标记仅用作各自XML片段的根(很可能)。Real