2013-02-21 22 views
0

我正在開發創建PowerShell腳本的第一步,該腳本將通過打印機日誌(可能使用get-WMI cmdlet)讀取並解析日誌。之後,我計劃將腳本輸出到.txt文件中,打印機的名稱,打印機使用次數的計數器(如果可能)以及日誌中的特定信息。解析文本文件並寫出數據

爲了做到這一點,我決定嘗試向後工作。下面是日誌將是什麼樣子的一小部分:

10   Document 81, A361058/GPR0000151814_1: owned by A361058 was printed on R3556 via port IP_***.***.***.***. Size in bytes: 53704; pages printed: 2                 20130219123105.000000-300 
10   Document 80, A361058/GPR0000151802_1: owned by A361058 was printed on R3556 via port IP_***.***.***.***. Size in bytes: 53700; pages printed: 2 

工作向後,只是專注於第一解析,我希望能夠明確獲得「/ GRP」,「R3446(一般,R * *,因爲這是打印機名稱)「,並獲取一個計數器,顯示特定打印機在日誌文件中出現的頻率。

它已經有一段時間,因爲我最後一次使用PowerShell的工作,但目前這是我已經設法以儘量實現我的目標是創建:

Select-String -Path "C:\Documents and Settings\a411882\My Documents\Scripts\Print Parse Test.txt" -Pattern "/GPR", " R****" -AllMatches -SimpleMatch 

的代碼不會產生任何錯誤,但是我也無法讓任何輸出出現在屏幕上以查看我是否捕獲了/ GRP和打印機名稱。目前我正在努力確保在收集任何計數器之前收集正確的輸出。任何人都可以幫助我,並告訴我我的代碼有什麼問題嗎?

謝謝!

編輯:修復了我的代碼導致沒有數據出現在屏幕上的一個小錯誤。此時此代碼輸出整行兩行測試文本,而不是僅輸出/ GPR和服務器名稱。新的輸出如下:

My Documents\Scripts\Print Parse Test.txt:1:10   Document 81, A361058/GPR0000151814_1: owned by A361058 was printed on 
R3556 via port IP_***.***.***.***. Size in bytes: 53704; pages printed: 2             
       20130219123105.000000-300 
My Documents\Scripts\Print Parse Test.txt:2:10   Document 80, A361058/GPR0000151802_1: owned by A361058 was printed on 
R3556 via port IP_***.***.***.***. Size in bytes: 53700; pages printed: 2 

我想嘗試有它最終看起來像以下:

/GPR, R****, count: ## (although for now I'm less concerned about the counter) 
+0

刪除'寫主機|'。您不能將空白命令傳輸到另一個命令中。 'Select-String'會自行輸出結果 – 2013-02-21 18:31:54

+0

Graimer:我最初嘗試不使用寫主機,但是每當我這樣做時,我也沒有得到任何輸出,所以我認爲我必須在某些情況下使用Write-Host方法 – Valrok 2013-02-21 18:36:17

+1

如果'select-string'沒有返回對象,那是因爲它沒有找到任何東西。它沒有找到任何東西的原因是因爲你拼錯了「GPR」。 「/ GRP」不是「/ GPR」:-) – 2013-02-21 18:48:39

回答

1

你可以試試這個。它僅在/GPR(和「打印在」上的「開」)存在時返回一行。

Get-Content .\test.txt | % { 
    if ($_ -match '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)') { 
     $_ -replace '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)', '$1,$2' 
    } 
} 

輸出:

/GPR,R3556 
/GPR,R3556 

我敢肯定有更好的正則表達式版本。我仍然在學習它:-)

編輯這是比較容易閱讀。正則表達式是仍然存在用於提取,但我濾除與/ GPR首先使用select-string代替行:

Get-Content .\test.txt | Select-String -SimpleMatch -AllMatches -Pattern "/GPR" | % { 
    $_.Line -replace '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)', '$1,$2' 
} 
+0

哦哇......正則表達式..如果要求不太多,可否解釋一下代碼?我從來沒有見過PowerShell基於正則表達式寫得這麼厲害。這是我認爲它正在做什麼,並想知道如果你能糾正我,所以我會理解代碼: – Valrok 2013-02-21 19:31:38

+0

它正在搜索/ GPS和「開」後的單詞, 「在\ s」可能「開」, 「\ w +」可能表示下一個詞, 但我不確定我明白'$ 1,$ 2'是否存在。 – Valrok 2013-02-21 19:32:26

+1

鬼臼內的東西是一個組。有些正在捕捉(商店價值),有些則不是。第一組匹配下一組(/ GPR)前的所有內容並將其丟棄。第二個匹配/ GPR並保持它。第三個等於第一個。然後我搜索「on」並將其扔掉(僅用於搜索R3556的位置)。然後我得到下一個單詞(R3556)並保留它,然後匹配該行的其餘部分。由於行中的所有內容都是匹配的,所有內容都將替換爲我指定的內容。我指定了'$ 1,$ 2',這意味着我在中間逗留的兩個小組。難以解釋:P – 2013-02-21 19:51:07

0

我通常與我匹配線的一個例子開始,並建立從一個正則表達式,代用於文本的可變部分的正則表達式元字符。這使得正則表達式更長,但稍後更直觀。

指定正則表達式給一個變量,然後使用該變量在後面的代碼保持正則表達式的繁瑣的細節塞滿了其餘代碼:

[regex]$DocPrinted = 
'Document \d\d, \w+/(\D{3})[0-9_]+: owned by \w+ was printed on (\w+) via port IP_[0-9.]+ Size in bytes: \d+; pages printed: \d+' 

get-content <log file> | 

foreach { 
if ($_ -match $DocPrinted) 
    { 
    $line -match $docprinted > $null 
    $matches 
    } 
}