我需要解析一个文件,当找到具有相同连接ID(在此示例中为655629)的行时,比较它们并仅保留不是“其他”的行
这两行,例如:
08/26-20:26:42.655629 [**] [1:9000003:0] troll [**] [Priority: 0] {TCP} 192.168.0.1:35964 -> 192.168.0.99:368
08/26-20:26:42.655629 [**] [1:1:0] other [**] [Priority: 0] {TCP} 192.168.0.1:35964 -> 192.168.0.99:368
这里的某个人已经非常友好地分享了这段代码,它基本上会返回我需要的每一行的部分,并按照我需要的方式进行格式化。
Get-Content $logFile -ReadCount 1 | % {
'|' + (($_.Split()[0, 9, 11, 4] -replace ':', '|') -join '|') + '|'
} | Out-File "C:\Log\logout.txt"
|08/26-20|26|42.655629|192.168.0.1|35964|192.168.0.99|368|troll|
|08/26-20|26|42.655629|192.168.0.1|35964|192.168.0.99|368|other|
但是,当有多条具有相同连接ID的行时,我只想保留一行(本例中为655629)。如果有多条线路具有相同的连接ID,我需要的线路不是“其他”
我只是为了比较而展示第一个indice [0]。我需要从所有行的最终输出中删除它。
例如,最终输出应如下所示:
|192.168.0.1|35964|192.168.0.99|368|troll|
|192.168.0.254|35964|192.168.0.99|368|troll|
|192.168.0.9|35964|192.168.0.99|368|other|
|192.168.0.199|35964|192.168.0.99|368|troll|
|192.168.0.199|35964|192.168.0.99|368|other|
非常感谢任何帮助!
答案 0 :(得分:2)
我强烈建议使用正则表达式解析输入并从子匹配中创建自定义对象,而不是像现在一样分割行。
$re = '^(.*?)\.(\d+) \S+ \S+ (\S+) \S+ \S+ \S+ (.*?):(\d+) -> (.*?):(\d+)'
Get-Content $logFile -ReadCount 1 | Where-Object {
$_ -match $re
} | ForEach-Object {
New-Object -Type PSObject -Property @{
Timestamp = $matches[1] #?
ConnectionID = $matches[2]
...
Source = $matches[4]
Destination = $matches[6]
}
}
这将允许您按字段值实际过滤数据:
... | Sort-Object ConnectionID -Unique | ...
可以通过Export-Csv
:
... | Export-Csv 'C:\path\to\output.txt' -NoType -Delimiter '|'
答案 1 :(得分:1)
如果要移除的最后一个字段始终是“其他”字段,则可以添加where-object过滤器以将其删除。
Get-Content $logFile -ReadCount 1 | % {
'|' + (($_.Split()[0, 9, 11, 4] -replace ':', '|') -join '|') + '|'
} | where-object {$_ -notlike "*other|"} | Out-File "C:\Log\logout.txt"
如果'其他'代表其他东西,你可以使用-UNIQUE选项,看看只过滤到每个的一个副本。问题是你当前没有为这些字段命名,你可以通过表达式来做。
(Get-Content $logFile -ReadCount 1 | select @{name="DateTime";Expression={$_.split(" ")[0].split(".")[0]}}, @{name="ConnectionID";Expression={$_.split(".")[1].split(" ")[0]}}, @{Name="IPAddress";Expression={$_.split()[9]}} | sort-object -unique IPAddress ) -join("|")