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