我需要从C#中的特定字符串中获取最后一次出现的日志跟踪,例如:
lines = File.ReadLines(logPath)
.SkipWhile(line => !line.Contains("param"))
.Take(20);
该代码有效,但是它从日志中首次出现的“ param”返回20行,而我需要最后一行。
答案 0 :(得分:1)
您可以创建一个(扩展)方法,该方法向后遍历源序列,直到找到与某个谓词匹配的项。在搜索匹配项时,请保留已查看过的项目堆栈,如果找到匹配项,则将其退回:
scanf
用法:
public static IEnumerable<T> SkipUntilLast<T>(
this IEnumerable<T> source, Func<T, bool> predicate)
{
var stack = new Stack<T>();
foreach(var item in source.Reverse())
{
if (predicate(item))
return stack;
stack.Push(item);
}
return Enumerable.Empty<T>();
}
请注意,lines = File.ReadLines(logPath).
.SkipUntilLast(line => line.Contains("param"))
.Take(20);
会将源序列放在缓冲区中,然后堆栈将执行类似的操作(取决于最后一个匹配是更靠近源尾还是源头)。您可以使用所需大小的队列来保存已检查的项目,因此在您的情况下,最多可以有20个项目。您还可以通过在谓词检查之前移动Reverse
来确定是否应在输出中包括匹配项。
样本文件
stack.Push
跳过直到包含“ param”的最后一行,然后接受下三行:
something
param foo
this
is
not
included
param bar
here
we
go
again
结果:
File.ReadLines("samplefile").SkipUntilLast(line => line.Contains("param")).Take(3);
答案 1 :(得分:0)
将行转换为“列表”或“数组”后,可以使用“最后”。如下所示:
lines = File.ReadLines(logPath)
.SkipWhile(line => !line.Contains("param"))
.ToList()
.Last();
答案 2 :(得分:0)
要查找与提供的谓词匹配的字符串的最后一次出现,我建议使用LastOrDefault
:
File.ReadLines(logPath)
.LastOrDefault(line => !line.Contains("param"));
否则,如果您需要所提到的20
中的最后一个,请使用Skip
和FirstOrDefault
:
File.ReadLines(logPath)
.SkipWhile(line => !line.Contains("param"))
.Skip(19)
.FirstOrDefault();
它也可以通过以下方式完成:
File.ReadLines(logPath)
.SkipWhile(line => !line.Contains("param"))
.Take(20)
.LastOrDefault();