查找文件中最后一次出现的字符串

时间:2018-12-24 16:22:13

标签: c#

我需要从C#中的特定字符串中获取最后一次出现的日志跟踪,例如:

lines = File.ReadLines(logPath)
        .SkipWhile(line => !line.Contains("param"))
        .Take(20);

该代码有效,但是它从日志中首次出现的“ param”返回20行,而我需要最后一行。

3 个答案:

答案 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中的最后一个,请使用SkipFirstOrDefault

File.ReadLines(logPath)
    .SkipWhile(line => !line.Contains("param"))
    .Skip(19)
    .FirstOrDefault();

它也可以通过以下方式完成:

File.ReadLines(logPath)
    .SkipWhile(line => !line.Contains("param"))
    .Take(20)
    .LastOrDefault();