2016-08-18 50 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 
    } 
}