2012-09-10 35 views
0

我想從日誌文件中提取一段信息。我正在使用的模式是節點名稱和命令的提示。我想提取命令輸出的信息並比較它們。考慮下面的示例輸出使用Java從日誌中提取某些模式

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 它是一個日誌文件,我在上面的代碼中讀取爲一個字符串。

+0

你有整個日誌作爲一個字符串? –

+0

我讀取文件作爲上述代碼的字符串。 –

+0

這樣一個字符串有多大?你有沒有測量需要時間?將日誌讀入一個字符串?尋找開始/停止或分裂?很難給出具體的解析優化,她的輸入與代碼不匹配。 –

回答

0

我的建議..

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; 
      } 
     } 
    } 
+0

或優化您的代碼,您可以從strLineString變量中刪除搜索到的字符串。在你重新分配開始的末尾,你寫strLineString = strLineString.subString(end); start = 0; – bhatanant2

0

這裏是我的建議:

使用正則表達式。這裏是一個:

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 

因此,要打破正則表達式:

首先,它跳過所有的跡象,直到它找到的第一個 「節點名>命令」,然後由一個數字。我們想要保留這個數字,知道哪個命令創建了輸出。接下來,我們抓住以下所有跡象,直到我們(使用lookahead)找到另一個NodeName或輸入的結尾。