【问题标题】:Comparing list against list, filtering/ignoring timestamp将列表与列表进行比较,过滤/忽略时间戳
【发布时间】:2013-09-02 13:24:20
【问题描述】:

我正在尝试创建一个程序,用于根据文件 A(已知良好)验证文件 B(潜在不良)的内容,并从潜在不良文件中删除每个已知良好行,只留下潜在不良行。我遇到的问题是每一行都包含一个时间戳。如何验证时间戳之后开始的行的内容?

I.E.文件 A:

MSI (c) (74:80) [08:09:43:718]: Resetting cached policy values
MSI (c) (74:80) [08:09:43:718]: Machine policy value 'Debug' is 0
MSI (c) (74:80) [08:09:43:718]: ******* RunEngine:

与文件 B:

MSI (c) (E8:DC) [18:35:18:573]: Resetting cached policy values
MSI (c) (E8:DC) [18:35:18:573]: Machine policy value 'Debug' is 0
MSI (c) (E8:DC) [18:35:18:573]: ******* RunEngine:

这些都应该被认为是平等的。 我没有一个不同的例子,但它基本上是一旦这些被删除后剩下的任何东西。

到目前为止我的代码:

Public Class Form1
Dim compto As New List(Of String)
Dim compfrom As New List(Of String)

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Standard("filea.LOG")
    Readfile("fileb.LOG")
    Writefile("difference.txt")
End Sub


Public Sub Standard(ByVal Path As String)
    Using r As StreamReader = New StreamReader(Path)
        Dim line As String = Nothing
        line = r.ReadLine
        Do While (Not line Is Nothing)
            line = r.ReadLine
            If Not compto.Contains(line) Then compto.Add(line)
        Loop
    End Using
End Sub

Public Sub Readfile(ByVal Path As String)
    Dim pattern As String = "{30}([A-Za-z0-9\-]+"
    Using r As StreamReader = New StreamReader(Path)
        Dim line As String = Nothing
        line = r.ReadLine
        Do While (Not line Is Nothing)
            line = r.ReadLine
            If Not compto.Contains(line) Then compfrom.Add(line)
        Loop
    End Using
End Sub

Public Sub Writefile(ByVal Path As String)
    Using sw As StreamWriter = New StreamWriter(Path)
        For Each line As String In compfrom
            sw.WriteLine(line)
            ListBox1.Items.Add(line)
        Next
    End Using
End Sub

End Class

到目前为止,此代码将删除完全匹配,但这就是我卡住的地方。任何帮助都会很棒。

谢谢。

解决方案编辑:

Public Sub Writefile(ByVal Path As String)
    Dim GetLine As Func(Of String, String) = Function(line) Regex.Match(line, "\]: (.*)").Groups(1).Value
    Dim Diff As New HashSet(Of String)(File.ReadLines("filea.log").Select(GetLine))
    Diff.SymmetricExceptWith(File.ReadLines("fileb.log").Select(GetLine))
    Using sw As StreamWriter = New StreamWriter(Path)
        For Each line As String In Diff
            sw.WriteLine(String.Join("", line))
            ListBox1.Items.Add(String.Join("", line))
        Next
    End Using
End Sub

【问题讨论】:

  • 您能否发布更多文件示例,显示您认为相同的几行,以及您认为不同的几行。
  • @MontyWild 由于格式问题编辑了帖子。
  • 你能编辑你的帖子吗?很难从您的评论中读出这些内容。
  • 正在讨论的文件有多大,将它们加载到内存中以使用 LINQ 进行处理是否可行?
  • @ZevSpitz 6,000+ 行和高达 10,000kb(到目前为止,代码可能稍后会适应更大的文件)我对 LINQ 一无所知,但现在会研究它。

标签: vb.net


【解决方案1】:

基于this 链接,试试这个:

Dim GetLine As Func(Of String,String) = Function(line) Regex.Match(line,"\]: (.*)").Groups(1).Value

'IF the timestamp is always at the same position, it may be more efficient to 
'avoid regular expressions. YMMV
GetLine = Function(line) line.Substring(32)

Dim Diff = New HashSet(File.ReadLines("filea.LOG").Select(GetLine))
Diff.SymmetricExceptWith(File.ReadLines("fileb.LOG").Select(GetLine))

【讨论】:

  • 这可能是一个比我更好的整体解决方案,但假设行头的长度是恒定的,你可以得到 Dim Getline... 行的 rif 并替换 File.ReadLines( ... @ 987654326@ 和 File.ReadLines( ... ).Substring(32) 并且不必为每行执行较慢的Regex
  • @MontyWild 如果您的意思是正则表达式速度较慢,因为它们每次都必须重新编译,Regex 上的静态方法会缓存 15 个(默认情况下)最后使用的正则表达式的编译。见here
  • @ZevSpitz 谢谢!将代码添加到 op,似乎可以正常运行。
【解决方案2】:

您似乎正在将File A 中的每一行与File B 中的每一行进行比较,并且行标题MSI (c) (74:80) [08:09:43:718]: 与此比较无关,并且它的长度是恒定的。

您可能会更改您的代码(4 个实例):

line = r.ReadLine

到:

line = r.ReadLine.Substring(32)

Substring() 带一个整数参数,返回字符串从指定字符位置开始的剩余部分。

【讨论】:

  • 除非文档包含偶尔的空白或分隔行,否则会因为字符串长度小于 32 而产生异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
相关资源
最近更新 更多