簡體   English   中英

如何在 Java 中將日志文件解析為 csv 文件

[英]How to parse log file to csv file in Java

我想讀取我的日志文件並通過 Java 放入 csv 文件。 我將如何將帶有這些分隔符的日志文件解析為 csv 文件,如下所示。

.log 文件:

2022-06-01 11:00:00 wt.nm=aa&wt.ti=t1&
2022-06-02 12:00:00 wt.nm=ab&wt.ti=t2&
2022-06-03 10:00:00 wt.nm=ac&wt.ti=t3&

日期和時間由空格分隔,名稱和標題由 wt.nm=/wt.ti 分隔,以 & 結尾

CSV 輸出:

date,time,name,title 
2022-06-01,11:00:00,aa,t1
2022-06-02,12:00:00,ab,t2
2022-06-03,10:00:00,ac,t3
import java.io.*;
public class test {
    public static void main(String[] args) {
        try{
            BufferedReader in = new BufferedReader(new FileReader("/Users/ts/Desktop/test/src/0606.log"));
            FileWriter wb = new FileWriter("/Users/ts/Desktop/testcsv.csv");
            String str;
            while((str=in.readLine()) != null) {
                System.out.println(str);
                wb.write(str);
            }
        }
        catch (IOException e) {
        }
    }
}

以下將進行轉換。

答案 01

如果日志的結構是固定的,您可以使用以下解決方案。

while ((str = in.readLine()) != null) {
    str = str.replaceAll(" wt.nm=|&wt.ti=| ", ",").replace("&", "");
    System.out.println(str);
    wb.write(str);
}

答案 02

如果結構不固定。 您可以使用模式匹配來提取相關字符串。 請參考以下內容。

while ((str = in.readLine()) != null) {
    
    String nm = "";
    String ti = "";
    // First Assuming Date and time willmbe always there.
    String [] parts =  str.split(" ");

    String tokenizingString = parts[2];
    String pattern1 = "wt.nm=";
    String pattern2 = "wt.ti=";

    Pattern p = Pattern.compile(Pattern.quote(pattern1) + "(.*?)" + Pattern.quote("&"));
    Matcher m = p.matcher(str);
    // Assumes the pattern occurs once, hence only getting the first matcher
    if (m.find()) {
        nm = m.group(1);
    }
    
    Pattern p2 = Pattern.compile(Pattern.quote(pattern2) + "(.*?)" + Pattern.quote("&"));
    Matcher m2 = p2.matcher(str);
    
    if (m2.find()) {
        ti = m2.group(1);
    }
    
    String logEntry = parts[0] + "," + parts[1] + "," + nm + "," + ti;
    System.out.println(logEntry);
}

數據中的格式(忽略前導日期和時間)如下所示:

  • wt.nm始終存在
  • wt.ti始終存在
  • wt.nm總是出現在wt.ti之前
  • 永遠不會有額外的名稱+值對(除了wt.nmwt.ti

但是,數據具有更一般的模式:

  • 一個(或多個)名稱+值對
  • 對於每個名稱+值對,名稱與值之間用=分隔
  • 每個名稱+值對由&其他對分隔

此外,很容易想象會遇到額外的名稱+值對(誰說這兩個永遠是相同的?為什么不在一行中有五個名稱+值?),或者可能是順序發生了變化( wt.ti可能出現在之前wt.nm ?)。

下面的代碼采用通用方法,使用輸入數據的通用模式。 我包含了一些示例數據來展示它是如何工作的。

  • 第一個輸入行—— "2022-06-01 11:00:00 wt.nm=aa&wt.ti=t1&" ——您的原始輸入之一
  • 第二行 – "2022-06-01 11:00:00 xxxxxxxxxxx=bb&" – 完全使用不同的“名稱”,並且只有一個名稱+值對(不是兩個): xxxxxxxxxxx=bb
  • 第三行—— "2022-06-01 11:00:00 xxxxxxxxxxx=cc&yyyyyyyyyyyy=t3&zzzzzzzz=99&" ——包括第三個名稱+值對: zzzzzzzz=99 誰說永遠只有兩個名稱+值對?
String[] lines = {
        "2022-06-01 11:00:00 wt.nm=aa&wt.ti=t1&",
        "2022-06-01 11:00:00 xxxxxxxxxxx=bb&",
        "2022-06-01 11:00:00 xxxxxxxxxxx=cc&yyyyyyyyyyyy=t3&zzzzzzzz=99&"
};
for (String line : lines) {
    System.out.println("original: " + line);
    String edit1 = line.replaceAll("&", " ");
    System.out.println("          " + edit1);

    StringTokenizer tokenizer = new StringTokenizer(edit1);
    StringBuilder finalLine = new StringBuilder();
    while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken();
        System.out.println("   token: " + token);
        if (token.contains("=")) {
            int positionOfEqualsSign = token.indexOf("=");
            String value = token.substring(positionOfEqualsSign + 1);
            finalLine.append(value);
        } else {
            finalLine.append(token);
        }
        if (tokenizer.hasMoreTokens()) {
            finalLine.append(",");
        }
    }
    System.out.println("   final: " + finalLine);
    System.out.println();
}

這是該代碼的輸出,其中包括許多額外的輸出,以便於理解:

original: 2022-06-01 11:00:00 wt.nm=aa&wt.ti=t1&
          2022-06-01 11:00:00 wt.nm=aa wt.ti=t1 
   token: 2022-06-01
   token: 11:00:00
   token: wt.nm=aa
   token: wt.ti=t1
   final: 2022-06-01,11:00:00,aa,t1

original: 2022-06-01 11:00:00 xxxxxxxxxxx=bb&
          2022-06-01 11:00:00 xxxxxxxxxxx=bb 
   token: 2022-06-01
   token: 11:00:00
   token: xxxxxxxxxxx=bb
   final: 2022-06-01,11:00:00,bb

original: 2022-06-01 11:00:00 xxxxxxxxxxx=cc&yyyyyyyyyyyy=t3&zzzzzzzz=99&
          2022-06-01 11:00:00 xxxxxxxxxxx=cc yyyyyyyyyyyy=t3 zzzzzzzz=99 
   token: 2022-06-01
   token: 11:00:00
   token: xxxxxxxxxxx=cc
   token: yyyyyyyyyyyy=t3
   token: zzzzzzzz=99
   final: 2022-06-01,11:00:00,cc,t3,99

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM