使用Linq对日志文件的行进行分组
我有一个日志文件中的字符串数组,格式如下:使用Linq对日志文件的行进行分组,linq,Linq,我有一个日志文件中的字符串数组,格式如下: var lines = new [] { "--------", "TimeStamp: 12:45", "Message: Message #1", "--------", "--------", "TimeStamp: 12:54", "Message: Message #2", "--------", "--------", "Message: Message #3"
var lines = new []
{
"--------",
"TimeStamp: 12:45",
"Message: Message #1",
"--------",
"--------",
"TimeStamp: 12:54",
"Message: Message #2",
"--------",
"--------",
"Message: Message #3",
"TimeStamp: 12:55",
"--------"
}
我想使用LINQ将由----分隔的每组行分组到一个列表中。基本上,我想要一个列表或类似的列表,其中每个内部列表包含4个字符串-2个分隔符、一个时间戳和一条消息
我应该补充一点,我希望尽可能使其通用,因为日志文件格式可能会改变
可以这样做吗?这样行吗
var result = Enumerable.Range(0, lines.Length / 4)
.Select(l => lines.Skip(l * 4).Take(4).ToList())
.ToList()
编辑:
这看起来有点粗糙,但我相信它可以清理干净
IEnumerable<List<String>> GetLogGroups(string[] lines)
{
var list = new List<String>();
foreach (var line in lines)
{
list.Add(line);
if (list.Count(l => l.All(c => c == '-')) == 2)
{
yield return list;
list = new List<string>();
}
}
}
假设您的结构始终是
delimeter
TimeStamp
Message
delimeter
public List<List<String>> ConvertLog(String[] log)
{
var LogSet = new List<List<String>>();
for(i = 0; i < log.Length(); i += 4)
{
if (log.Length <= i+3)
{
var set = new List<String>() { log[i], log[i+1], log[i+2], log[i+3] };
LogSet.Add(set);
}
}
}
还是在林克
public List<List<String> ConvertLog(String[] log)
{
return Enumerable.Range(0, lines.Length / 4)
.Select(l => lines.Skip(l * 4).Take(4).ToList())
.ToList()
}
实际上,您应该能够比返回列表>做得更好。如果您使用的是C4,则可以将每组值投影到一个动态类型中,其中冒号前的字符串成为属性名,值位于左侧。然后创建一个自定义迭代器,该迭代器读取这些行,直到每个集合中出现结尾,然后返回该行。在MoveNext上,阅读下一组行。冲洗并重复,直到EOF。我现在没有时间写一个完整的实现,但是我在CSV中阅读和在动态对象上使用LINQ的示例可能会让您了解您可以做什么。看见注意:这个示例是用VB编写的,但同样的操作也可以用C编写,只需做一些修改
迭代器实现还有一个额外的好处,即在解析之前不必将整个文档加载到内存中。使用此版本,一次只能加载一组块的数量。它允许您处理非常大的文件。Ah-自定义迭代器听起来很完美。我会尝试一下。我添加了一条注释,说我希望解决方案尽可能通用,但谢谢。@RB我添加了另一个代码段;看看这是否有帮助。根据你的编辑,我接受这个答案。非常感谢: