[英]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.nm
和wt.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.