繁体   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