【问题标题】:Loop thru tabbed data and get blocks of segemented information循环通过选项卡式数据并获取分段信息块
【发布时间】:2013-04-30 18:14:26
【问题描述】:

我有一个纯文本文件,其中包含选项卡式信息,如下所示

ADVMONITOR "WINOSSPI-RPCService-Win2k"
DESCRIPTION "Checks the 'Remote Procedure Call (RPC)' Windows 2000 service and its corresponding process"
INTERVAL "5m2s"
SCRIPTTYPE "VBScript"
MULTISOURCE
INSTANCEMODE  ONCE
MAXTHRESHOLD
SEPARATORS "    "
ICASE
PROGRAM "Process"
    DESCRIPTION "Returns the number of running 'svchost.exe' processes;"
    MONPROG "opcntprocs.exe WINOSSPI-RPCService-Win2k-Process svchost"
PROGRAM "Service"
    DESCRIPTION "Returns  values that correspond to different states of the service 'RPC Service'"
    MONPROG "opcntservice_chk.bat RpcSs WINOSSPI-RPCService-Win2k-Service"
MSGCONDITIONS
    INSTANCERULE "Combined Service and Process Monitor; suppress messages caused by same case;"
    ID "d5ca6823-37d4-4581-886a-2aad3462d9e0"
    DESCRIPTION "Checks the services and processes"
    CONDITION_ID "0cdb88dd-0338-47d3-a5f5-e4d982e8a1a9"
    CONDITION

我需要的是从每个不同的块中获取信息,我可以将这些信息导入到数据库中,但是我无法通过不同的块进行良好的迭代以从每个块中获取正确的数据良好且可识别的方式。

我尝试使用名为tabbedLinesTree 的类根据选项卡识别块,这会将所有选项卡式文本转换为 XML,这也很有用,但不同的字段不会以字段名称或任何其他方式显示确定我们正在通过哪个街区。

正在恢复...我想通过该文件并为每个 PROGRAM 块获取(作为示例)一个具有 PROGRAM 名称的数组,DESCRIPTIONMONPROG 用于该块...

不知道如何概念化这个,你能帮我解决这个问题吗?

我擅长 PHP,但如果需要,我可以实现任何其他解决方案。

Ps:某些块可以有更多的选项卡或更多的信息字段(行)。

--- 在 NIGEL 的回答之后添加的文本下方 ---

第二个文本示例...

SYNTAX_VERSION 5

LOGFILE "OvSvcDiscErrorLog"
DESCRIPTION "Self-Management OvService Discovery agent error log"
LOGPATH "<OvSvcDiscErrorLog>"
INTERVAL "5m"
CHSET ASCII
FROM_LAST_POS
NO_LOGFILE_MSG
CLOSE_AFTER_READ
SEPARATORS "    "
MSGCONDITIONS
                DESCRIPTION "[E01-001] EXCEPTION while installing policy"
                SUPP_DUPL_IDENT "3m"
                    COUNTER_THRESHOLD 0
                CONDITION_ID "17adc1d1-32cf-42ca-be5f-1cf784f19026"
                CONDITION
                    TEXT "<*> \\[E01-001\\] EXCEPTION while installing policy <*.polname>" SEPARATORS "     "
                SET
                    SEVERITY Critical
                    APPLICATION "OVO/Win"
                    MSGGRP "OVO"
                    OBJECT "OvSvcDiscAgent"
                    TEXT "[E01-001]EXCEPTION while installing policy "`

【问题讨论】:

  • 你能指出输入文件格式的标签吗?
  • 嗨,Emiliano,第二个例子看起来像一个树状结构。例如。 SETMSGCONDITIONS 的子代,SEVERITYAPPLICATIONSET 的子代。这看起来对吗?
  • 大家好!抱歉,没有看到你最后的 cmets... Jamie,谢谢你的回答,你的意思是什么?要我突出显示标签吗?我能做到。奈杰尔,就是这样! :)
  • 编写简单的解析器github.com/rjhdby/HpomMetricsParser

标签: php text identify tabbed


【解决方案1】:

您好,这不是很漂亮,但很有效。下面代码产生的最终结果是这样的;

Array
(
    [PROGRAM_Process] => Array
        (
            [name] => Process
            [DESCRIPTION] => Returns the number of running 'svchost.exe' processes;
            [MONPROG] => opcntprocs.exe WINOSSPI-RPCService-Win2k-Process svchost
        )

    [PROGRAM_Service] => Array
        (
            [name] => Service
            [DESCRIPTION] => Returns  values that correspond to different states of the service 'RPC Service'
            [MONPROG] => opcntservice_chk.bat RpcSs WINOSSPI-RPCService-Win2k-Service
        )

)

它的核心是 PHP parse_ini_file() 函数。 parse_ini_file() 将正常.ini 格式的文本文件作为其输入,例如;

[first_section]
one = 1
five = 5
animal = BIRD

[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"

并返回一个关联数组。下面的大部分代码都与修改输入文件有关,以使其适合parse_ini_file()。重整由foreach 循环完成。重组后的数据组装在数组$arr_ini中。

不幸的是,parse_ini_file() 只会将文件(不是字符串)作为其输入,所以我不得不使用一个名为 tmp.ini 的临时文件。

<?php

$tmp_file = 'tmp.ini';
$input_file = 'input.txt';
$arr_input = explode("\r\n", file_get_contents($input_file));
$arr_ini = array();
$flg_collate = false;

foreach($arr_input as $line) {

  $split = explode(' ', trim($line), 2);

  if ($flg_collate) {
    if (substr($line, 0, 1) == ' ') {
      $arr_ini[] = $split[0].'='.$split[1];
    } else {
      $flg_collate = false;
    }
  }

  if ($split[0] == 'PROGRAM') {
    $without_quotes = trim($split[1], '"');
    $arr_ini[] = "[PROGRAM_$without_quotes]";
    $arr_ini[] = "name = {$split[1]}";
    $flg_collate = true;
  }
}

file_put_contents($tmp_file, implode("\r\n", $arr_ini));
$arr_result = parse_ini_file($tmp_file, true);

echo "<h1>Reformed array</h1><xmp>".print_r($arr_ini, true)."</xmp>";
echo "<h1>Result as an Array</h1><xmp>".print_r($arr_result, true)."</xmp>";

?>

结果是$arr_result。第一个echo 输出一个中间步骤。第二个echo 输出结果。

希望对您有所帮助。

【讨论】:

  • 嗨@Nigel!谢谢您的回答。我在这里发现了两件事让我相信它不会起作用。首先不是我需要识别的所有块都以“PROGRAM”开头,其次一些块可以在行的开头有不同的选项卡(有时是一个或两个,有时是三个、四个、五个或更多)源更改。
  • 您在发布原始问题后的第二天将第二个示例添加到您的问题中。当您提出问题然后稍后更改时,通常的做法是明确表明您已更改问题,通常通过添加词 Edit 或类似的词。这样就不会让回答你最初问题的人看起来很愚蠢。
  • 抱歉@Nigel,实际上你觉得自己很愚蠢并不是我的本意。我不认为你看起来那样,因为你向我提供了第一个答案,表明你愿意提供帮助,而且这是一个很好的答案,但没有涵盖我需要的所有内容。抱歉,如果我不够清楚,所以我需要添加我添加到问题中的新代码,以显示可能的变体的外观,但请阅读我的原始帖子并查看 PS,它清楚地表明“一些块可以有更多标签”。
  • 再次感谢您的回答,如果您不想再根据这种困惑给我写信,我会理解的,但是……这是我有史以来的第一个问题,我不知道所有的规则,我不打算按照你说的去做......啊......我所做的唯一编辑是添加第二个示例,我没有更改任何内容,只对您的回复发表评论以提供更多详细信息.再次感谢您!
  • 对不起,我不是故意的,我好像在警告你。这没什么大不了的,只是礼仪的一个小点。但感谢您按照我的建议重新编辑您的问题。我很感激:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 2021-12-06
  • 2016-02-23
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多