C# 将日志文件转换为CSV

C# 将日志文件转换为CSV,c#,csv,export-to-csv,powerpivot,weblog,C#,Csv,Export To Csv,Powerpivot,Weblog,我必须将(Squid Web代理服务器)日志文件转换为CSV文件,以便将其加载到powerpivot中以分析查询。 因此,我应该如何开始,任何帮助将不胜感激。 我必须使用C语言完成此任务,日志如下所示: 格式:时间戳已用客户端操作/代码大小方法URI标识符层次结构/来自内容 1473546438.145 917 5.45.107.68 TCP_DENIED/403 4114 GET http://atlantis.pennergame.de/pet/ - NONE/- text/html

我必须将(Squid Web代理服务器)日志文件转换为CSV文件,以便将其加载到powerpivot中以分析查询。 因此,我应该如何开始,任何帮助将不胜感激。 我必须使用C语言完成此任务,日志如下所示:

格式:时间戳已用客户端操作/代码大小方法URI标识符层次结构/来自内容

1473546438.145 917 5.45.107.68 TCP_DENIED/403 4114 GET http://atlantis.pennergame.de/pet/ - NONE/- text/html 1473546439.111 3 146.148.96.13 TCP_DENIED/403 4604 POST http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService - NONE/- text/html 1473546439.865 358 212.83.168.7 TCP_DENIED/403 3955 GET http://www.theshadehouse.com/left-sidebar-post/ - NONE/- text/html 1473546439.985 218 185.5.97.68 TCP_DENIED/403 3600 GET http://www.google.pl/search? - NONE/- text/html 1473546440.341 2 146.148.96.13 TCP_DENIED/403 4604 POST http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService - NONE/- text/html 1473546440.840 403 115.29.46.240 TCP_DENIED/403 4430 POST http://et.airchina.com.cn/fhx/consumeRecord/getCardConsumeRecordList.htm - NONE/- text/html 1473546441.486 2 52.41.27.39 TCP_DENIED/403 3813 POST http://www.deezer.com/ajax/action.php - NONE/- text/html 1473546441.596 2 146.148.96.13 TCP_DENIED/403 4604 POST http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService - NONE/- text/html 1473546438.145 917 5.45.107.68 TCP_拒绝/403 4114获取http://atlantis.pennergame.de/pet/ -无/-text/html 1473546439.1113146.148.96.13 TCP_被拒绝/4034604帖子http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService -无/-text/html 1473546439.865 358 212.83.168.7 TCP_拒绝/403 3955获取http://www.theshadehouse.com/left-sidebar-post/ -无/-text/html 1473546439.985218 185.5.97.68 TCP_拒绝/4033600获取http://www.google.pl/search? - 无/-text/html 1473546440.341 2 146.148.96.13 TCP_被拒绝/403 4604发布http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService -无/-text/html 1473546440.840 403 115.29.46.240 TCP_被拒绝/403 4430帖子http://et.airchina.com.cn/fhx/consumeRecord/getCardConsumeRecordList.htm -无/-text/html 1473546441.486 2 52.41.27.39 TCP_被拒绝/4033813帖子http://www.deezer.com/ajax/action.php -无/-text/html 1473546441.596 2 146.148.96.13 TCP_被拒绝/403 4604帖子http://mobiuas.ebay.com/services/mobile/v1/UserAuthenticationService -无/-text/html
CSV是一个带分隔符的文件,其字段分隔符为,。几乎所有程序都允许您指定不同的字段和记录分隔符,使用和作为默认值

如果文件不包含多个缩进空格,则可以将其视为带分隔符的文件。可以使用regex
\s{2,}
将多个空格替换为单个空格,例如:

var regex=new Regex(@"\s{2,}");
var original=File.ReadAllText(somePath);
var delimited=regex.Replace(original," ");
File.WriteAllText(somePath,delimited);
Power BI Desktop已允许您使用空间作为分隔符。即使没有,也可以通过将模式更改为
\s+
,将所有空格替换为逗号,即:

var regex=new Regex(@"\s+");
...
var delimited=regex.Replace(original,",");
...
日志文件很大,因此减少它们使用的内存量是一个非常好的主意。如果使用
ReadLines
一次读取一行,进行替换并写出,则可以避免读取内存中的整个文件:

using(var writer=File.CreateText(targetPath))
{
    foreach(var line in File.ReadLines(somePath))
    {
        var newline=regex.Replace(line," ");
        writer.WriteLine(newline);
    }
}

与加载数组中所有行的
ReadAllLines
不同,
ReadLines
是一个迭代器,一次读取并返回一行

CSV是一个带分隔符的文件,其字段分隔符为,。几乎所有程序都允许您指定不同的字段和记录分隔符,使用和作为默认值

如果文件不包含多个缩进空格,则可以将其视为带分隔符的文件。可以使用regex
\s{2,}
将多个空格替换为单个空格,例如:

var regex=new Regex(@"\s{2,}");
var original=File.ReadAllText(somePath);
var delimited=regex.Replace(original," ");
File.WriteAllText(somePath,delimited);
Power BI Desktop已允许您使用空间作为分隔符。即使没有,也可以通过将模式更改为
\s+
,将所有空格替换为逗号,即:

var regex=new Regex(@"\s+");
...
var delimited=regex.Replace(original,",");
...
日志文件很大,因此减少它们使用的内存量是一个非常好的主意。如果使用
ReadLines
一次读取一行,进行替换并写出,则可以避免读取内存中的整个文件:

using(var writer=File.CreateText(targetPath))
{
    foreach(var line in File.ReadLines(somePath))
    {
        var newline=regex.Replace(line," ");
        writer.WriteLine(newline);
    }
}

与加载数组中所有行的
ReadAllLines
不同,
ReadLines
是一个迭代器,一次读取并返回一行

它已经接近CSV了,所以请逐行阅读并将每一行稍微整理一下:

...
line = line
  .Replace("   ", " ")  // compress 3 spaces to 1
  .Replace("  ", " ")   // compress 2 spaces to 1
  .Replace("  ", " ")   // compress 2 spaces to 1, again
  .Replace(" ", "|")    // replace space by '|'
  .Replace(" - ", "|"); // replace  -  by '|'
您可能需要对TCP_DENIED/403等字段进行调整

这将为您提供一个分隔行。易于转换为所需的任何分隔符。或将其拆分:

// write it out or process it further    
string[] parts = line.split('|');

它已经接近CSV,所以请逐行阅读,并将每行稍微整理一下:

...
line = line
  .Replace("   ", " ")  // compress 3 spaces to 1
  .Replace("  ", " ")   // compress 2 spaces to 1
  .Replace("  ", " ")   // compress 2 spaces to 1, again
  .Replace(" ", "|")    // replace space by '|'
  .Replace(" - ", "|"); // replace  -  by '|'
您可能需要对TCP_DENIED/403等字段进行调整

这将为您提供一个分隔行。易于转换为所需的任何分隔符。或将其拆分:

// write it out or process it further    
string[] parts = line.split('|');
公共静态类SquidWebProxyServerCommaSeparatedWriter
{
公共静态void WriteToCSV(字符串目标,IEnumerable serverLogEntries)
{
var lines=serverLogEntries.Select(ConvertToLine);
File.writeAllines(目标,行);
}
专用静态字符串转换器行(SquidWebProxyServerLogEntry serverLogEntry)
{
返回字符串.Join(@“,”,serverLogEntry.Timestamp,serverLogEntry.Appeased.ToString(),
serverLogEntry.ClientIPAddress、serverLogEntry.ActionCode、serverLogEntry.Size.ToString(),
serverLogEntry.Method.ToString(),serverLogEntry.Uri,serverLogEntry.Identity,
serverLogEntry.HierarchyFrom、serverLogEntry.MimeType);
}
}    
公共静态类SquidWebProxyServerLogParser
{
公共静态IEnumerable解析(FileInfo FileInfo)
{
使用(var streamReader=fileInfo.OpenText())
{
字符串行;
而((row=streamReader.ReadLine())!=null)
{
收益率返回分析行(行)
}
}
}
私有静态SquidWebProxyServerLogEntry ParseRow(字符串行)
{
var fields=row.Split(新[]{“\t”,”“},StringSplitOptions.None);
返回新的SquidWebProxyServerLogEntry
{
时间戳=字段[0],
已用=int.Parse(字段[1]),
ClientIPAddress=字段[2],
ActionCode=字段[3],
Size=int.Parse(字段[4]),
方法=
(SquidWebProxyServerLogEntry.MethodType)
Parse(typeof(SquidWebProxyServerLogEntry.MethodType),字段[5]),
Uri=字段[6],
标识=字段[7],
HierarchyFrom=字段[8],
MimeType=字段[9]
};
}
公共静态IEnumerable解析(IEnumerable rows)=>rows.Select(ParseRow);
}
公共密封类SquidWebProxyServerLogEntry
{
公共枚举方法类型
{
Get=0,
员额=1,
Put=2
}
公共字符串时间戳{get;set;}
公共整数