2016-08-18 44 views
1

我与powershell一起跌跌撞撞。Powershell:从日志文件中提取数据以创建新对象

我有脚本解析我们感兴趣的是在数百PC的提取两个类型的交易相同的日志文件。

这一行做的模式匹配保存日志的每一行中包含多行一个变量。我将匹配对象转换为字符串,以便稍后进行拆分。

$strLogEvents = select-string -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* -pattern '(doFolderDocSearch ends, duration)|(doDocSearch ends, duration)' | ForEach-Object {$_.ToString()} 

这里是$ StrLogEvents适用于单个PC

\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log:325:Wed 08/17 10:24:44.983 PerformanceContext: 59:Info2 [10728] System call doDocSearch ends, duration 60203 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:886:Fri 08/05 16:23:14.249 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 1796 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:963:Fri 08/05 16:23:27.901 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 250 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1046:Fri 08/05 16:23:41.625 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 171 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1422:Sun 08/07 23:08:49.107 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 250 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1786:Sun 08/07 23:09:42.750 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 407 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1847:Sun 08/07 23:10:05.494 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 454 ms 

对于每一行我只在再培训的计算机名,日期,时间,系统调用,持续时间以毫秒为单位的类型有趣。

我还可以分手字符串数组与此:

$ParsedLogEvents = $strLogEvents | ForEach-Object {$_.split("\, ",[System.StringSplitOptions]::RemoveEmptyEntries)} 

在$ ParsedLogEvents的字符串现在包含一个清洁线用于每个数据的“片”

实施例:每个项目都是上它是自己的路线。我添加了***来表示我想保留的行。

naimc***-PCName 
c$ 
ProgramData 
IS 
Logs 
DMS 
OUTLOOK.log_bak:4602:Mon 
08/15*** -Date 
14:36:01.667 -Time 
PerformanceContext: 
59:Info2 
[10928] 
System 
call 
doDocSearch ***-EventType 
ends 
duration 
47 ***-Duration 
ms 
naimc 
c$ 
ProgramData 
Osler 
IS 
Logs 
DMS 
OUTLOOK.log_bak:4610:Mon 
08/15 
14:36:01.748 
PerformanceContext: 
59:Info2 
[10928] 
System 
call 
doDocSearch 
ends 
duration 
31 
ms 

我想我必须处理每一行作为单个变量。 (不知道如何做这个简单的部分)。在我可以简单地使用$ ParsedLogEvents [lineNumber]来返回我想保留的行的记录来创建一个哈希表或一个对象后。这将允许我保存为CSV或导出到SQL数据库。我现在无法做到这一点,因为每一行所有的原始事件都在这个大阵列里面。

有什么建议吗?我正朝着正确的方向前进吗?

回答

3

经由正则表达式模式的命名组不要在Select-String场解析:

$report = select-string ` 
    -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* ` 
    -pattern ('(?<date>.+? .+?) ' + 
     '(?<time>.+?) .+? ' + 
     '(?<syscall>doFolderDocSearch|doDocSearch) ends, duration ' + 
     '(?<duration>.+?) ms') ` 
| %{ 
    $g = $_.matches[0].groups 
    @{ 
     computer = $Cmpname 
     date = $g['date'].value 
     time = $g['time'].value 
     syscall = $g['syscall'].value 
     duration = $g['duration'].value 
    } 
} 

会产生如$report[1].computer访问的对象的阵列,$report[1].date,等:

Name       Value 
----       ----- 
date       Wed 08/17 
time       10:24:44.983 
syscall      doDocSearch 
computer      naimc 
duration      60203 
+0

非常好,但太硬核我的理解。出于某种原因,你的原始建议没有返回任何结果,但我做了一个补充 – user3019228

+0

也许你正在使用powershell2或3?代码在PS4上运行。 – wOxxOm

0

非常好!这是我看到的正则表达式命名组的第一个例子

由于某些原因,您的原始样本没有返回任何结果,它运行了几分钟但没有捕获任何结果。我不得不打破你的例子在一小部分,以了解这个概念

我保持我的基本线进行初始解析,留在matchinfo格式。

$strLogEvents = select-string -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* -pattern '(doFolderDocSearch ends, duration)|(doDocSearch ends, duration)' 

他们在第二个选择字符串中传递了Matchinfo.Line,它有你的代码文本工作并且速度很快。

$report = $strLogEvents | select-string -Inputobject {$_.line} -pattern ('(?<date>.+? .+?) ' + '(?<time>.+?) .+? ' + '(?<syscall>doFolderDocSearch|doDocSearch) ends, duration ' + '(?<duration>.+?) ms') | %{ 
    $g = $_.matches[0].groups 
    @{ 
     computer = $Cmpname 
     date = $g['date'].value 
     time = $g['time'].value 
     syscall = $g['syscall'].value 
     duration = $g['duration'].value 
    } 
}