【问题标题】:Extracting certain pattern from log using Java使用Java从日志中提取特定模式
【发布时间】:2012-09-10 15:17:33
【问题描述】:

我想从日志文件中提取一条信息。我使用的模式是节点名和命令的提示。我想提取命令输出的信息并进行比较。考虑如下示例输出

    NodeName > command1

    this is the sample output 

    NodeName > command2  

    this is the sample output

我已经尝试了以下代码。

public static void searchcommand( String strLineString) 
    {


             String searchFor = "Nodename> command1";
             String endStr = "Nodename";
             String op="";
             int end=0;
              int len = searchFor.length();
              int result = 0;
              if (len > 0) {  
              int start = strLineString.indexOf(searchFor);
              while(start!=-1){
      end = strLineString.indexOf(endStr,start+len);

              if(end!=-1){
                  op=strLineString.substring(start, end);

              }else{
                  op=strLineString.substring(start, strLineString.length());
              }
              String[] arr = op.split("%%%%%%%"); 
              for (String z : arr) {
                  System.out.println(z);
                }

                  start = strLineString.indexOf(searchFor,start+len);


              }

              }



    }

问题是代码太慢而无法提取数据。还有其他方法吗?

编辑 1 它是我在上面的代码中作为字符串读取的日志文件。

【问题讨论】:

  • 你有整个日志作为一个字符串吗?
  • 我将文件作为上述代码的字符串读取。
  • 这样的字符串有多大?你衡量过什么需要时间吗?将日志读入字符串?寻找开始/停止或分裂?如果您的输入与代码不匹配,则很难给出具体的解析优化。

标签: java extract file-read


【解决方案1】:

我的建议..

public static void main(String[] args) {
        String log = "NodeName > command1 \n" + "this is the sample output \n"
                + "NodeName > command2 \n" + "this is the sample output";

        String lines[] = log.split("\\r?\\n");
        boolean record = false;
        String statements = "";
        for (int j = 0; j < lines.length; j++) {
            String line = lines[j];         
            if(line.startsWith("NodeName")){

                if(record){
                    //process your statement
                    System.out.println(statements);
                }

                record = !record;
                statements = ""; // Reset statement
                continue;
            }

            if(record){             
                statements += line;
            }
        }
    }

【讨论】:

  • 或者为了优化您的代码,您可以从您的 strLineString 变量中删除搜索到的字符串。在你重新分配 start 的最后,你写 strLineString = strLineString.subString(end);开始 = 0;
【解决方案2】:

这是我的建议:

使用正则表达式。这是一个:

    final String input = "    NodeName > command1\n" +
            "\n" +
            "    this is the sample output1 \n" +
            "\n" +
            "    NodeName > command2  \n" +
            "\n" +
            "    this is the sample output2";

    final String regex = ".*?NodeName > command(\\d)(.*?)(?=NodeName|\\z)";

    final Matcher matcher = Pattern.compile(regex, Pattern.DOTALL).matcher(input);

    while(matcher.find()) {
        System.out.println(matcher.group(1));
        System.out.println(matcher.group(2).trim());
    }

输出:

1
this is the sample output1
2
this is the sample output2

所以,分解正则表达式:

首先,它会跳过所有符号,直到找到第一个“NodeName > 命令”,然后是一个数字。我们要保留这个数字,以了解哪个命令创建了输出。接下来,我们抓取以下所有标志,直到我们(使用前瞻)找到另一个 NodeName,或者输入的结尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多