2011-12-11 24 views
4

我試圖從一些(大)文本文件中提取一組數據。基本上,每一行看起來是這樣的:獲取powershell正則表達式捕獲到表

2011-12-09 18:20:55, ABC.EXE[3b78], The rest of the line... 

我想獲得的日期和括號之間的位(進程ID),然後編譯的表。第二階段的任務是對這個表進行分組,這樣我就可以得到每個進程id的最早日期,實際上給了我每個進程id的第一個日誌條目的日期和時間,它有望接近該實例的開始時間的過程。

到目前爲止我有什麼(拆分到不同的行可讀性)

gci -filter *.log -r 
| select-string '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}), ABC.EXE\[(.{4})' 
| % { $_.matches } | % { $_.groups } | % { $_.value } 

吐出的捕獲。我想忽略第一個捕獲,並將第二個和第三個結合到同一行。

幫助? 請問?

編輯: DOH!無法回答我自己的問題。所以...

好的,我想我是在正確的軌道上。一個SO質疑here幫我弄的各個部分,我想,即:

$_.matches[0].groups[1].value, $_.matches[0].groups[2].value 

然後,MSDN文章here展示瞭如何「叢」中的位爲對象,這使得它能夠被分組/排序/操縱。最終結果

gci -filter *.log | select-string '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}), ABC.EXE\[(.{4})' 
| % { new-object object 
    | add-member NoteProperty Name $_.matches[0].groups[1].value -passthru 
    | add-member NoteProperty PId $_.matches[0].groups[2].value -passthru } 

相當混亂,因此,如果有人知道的更清潔的方式做到這一點,請讓我知道。

回答

4

其中New-Object cmdlet支持接收性能的哈希表中的參數-Property您可以創建新的對象在PowerShell中V2簡單:

New-Object PSObject -Property @{ 
    Name = $_.matches[0].groups[1].value 
    PId = $_.matches[0].groups[2].value 
} 

一般來說,我會做處理有點不同,雖然:

# prepare table 
$data = $(switch -Regex -File filename { 
    '^[^,]+' { $date = [datetime]$Matches[0] } 
    '(?<=\[)[^\]]+' { $id = $Matches[0] } 
    '$' { New-Object PSObject -Property @{ 
     Date = $date 
     PId = $id 
    } } 
}) 

使用switch -regex已經成爲一個很好的方式(至少對我來說)爲文本數據進行快速和骯髒的解析器。使用-Regex,所有匹配的案例都將運行,在這種情況下全部匹配(所以這只是將匹配的不同部分分開的便利)。第一個抓取日期和時間並將其存儲在變量中(甚至作爲DateTime值);第二個獲得進程ID,第三個匹配在一行的末尾,將它們放在一起。

只是個人的喜好,雖然;我其實從來沒有用過Select-String

$data | 
    group PId | 
    foreach { New-Object PSObject -Property @{ 
     PId = $_.Name 
     MinDate = @($_.Group | sort Date)[0].Date 
    } } 

這隨後通過進程ID使用剛編譯的數據,組,並輸出具有用於每個最小日期的ID。

請注意,這更像是一種「看起來不錯的代碼」方法。如果你正在處理的文件是真的是大,你可能想要更有效的方法。

+0

太棒了,那就是我想要的東西!我從來沒有遇到Powershell中的switch語句。我喜歡 –

+0

你可以做一個'Get-Help about_switch'。它非常靈活。 – Joey

+0

+1用於New-Object上的-Property開關。 –