2014-09-19 54 views
0

對不起,如果標題不是很清楚,我認爲我的問題的一部分是我可以'想想清楚描述我想要達到什麼目的的方法,但這並沒有幫助我找到任何可能有所幫助的東西。Powershell - 如何從日誌文件條目中具有時間戳的基於文本的日誌文件中選擇一段文本

我想創建一個通用的腳本/函數,我可以傳遞2個時間值,開始時間和結束時間,將輸出這兩個時間戳之間的所有日誌文件條目。這將成爲腳本的核心部分,從通常每天超過1GB的日誌文件中提取日誌文件條目的非常短的時間跨度,並且非常難以在文件查看器或編輯器中有效地進行操作,因此需要花費大量時間從相關的dta文件中提取相關的dta,目的是爲開發人員提供數據以幫助調查問題。

日誌文件是不同的格式,但大多數的這些遵循下面的一般格式爲:

2418 22:19:58: CTracker::ReadAvlPackets - ENTER ... 
b18 22:19:58: SICInterfaceApp::ListenerRead: Qtype < 15> Subtype < 27> #8597208 From <¸i`  > 
b18 22:19:58: CTracker::OnListenerRead - PktPrc: 0x00000001 
2418 22:20:00: cAvlComIMobile::GetData - ErrSev: 0x00000000 
2418 22:20:02: cAvlComIMobile::GetData - ErrSev: 0x00000000 

我創建了一個基本功能:

function Get-LogExtract ($StartTime){ 
$Log = "path-to-log-file" 
Get-Content $Log | 
ForEach-Object { 
    $parts = $_ -split ' ' 
    if ($parts[1] -eq $StartTime) { 
      $_ 
     } 
    } 
} 

這要是我把它使用運行下面的命令行

Get-LogExtract 22:19:58: 

它只會輸出具有時間的日誌文件行22:19:58的郵票:在這條線上,這很好,這是我最初想要達到的目標,但是由於這一點,要求已經擴大。

我現在想要做的是提供一個開始時間和結束時間,並在這些輸出之間有所有行。

我試圖實現一個做while while循環來做到這一點,但明顯沒有得到任何地方,因爲我無法實現我想達到的目標。

所以我有幾個問題。

1. is there a better way to tackle what I am trying to acheive? 
    2. if not, how can I implement a loop to acheive my goal? 

更新的代碼:

OK,所以這裏的扭捏由PSGuy以下,其工作原理治療與對每一行:

時間戳條目日誌文件作爲建議的代碼段
function Get-LogExtract ($StartTime, $EndTime) { 
$Log = "path-to-log-file" 
Get-Content $Log | 
    ForEach { 
    $parts = $_ -split ' ' 
     if ($parts[1] -ge $StartTime -and $parts[1] -le $EndTime) { 
      $_ 
     } 
    } 
} 

回答

1

你可以在這裏做幾件事。第一個是,如果你想有一個真正的日期時間對象,那麼你就可以運行的System.DateTime類的以下靜態方法:

[DateTime]::Parse($Time) # 22:19:58 == Friday, September 19, 2014 10:19:58 PM 

你也可以做字符串比較,因爲對一個字符串的任何比較操作將通過Char值評估每個字符,因此「22:19:59」-gt「22:19:58」爲真。

我認爲轉換爲DateTime格式對你來說會更容易,但是,做一個簡單的字符串比較是可行的。例如:

如果$ line [$ I] -ge「22:19:59」和$ line [$ I] -le「23:59:59」理論上可用於您的腳本/函數。我也建議做一個for循環來遍歷日誌文件的每一行,但是,這不是必需的。如果我沒有在pipleline中使用實際的對象,我可以調用一個靜態的方法來處理對象本身,我不是那種對foreach-object cmdlet的忠實粉絲。在這裏,這只是簡單的字符串工作,我會親自使用for循環,但這都是一個偏好問題。 for構造如下所示:

$logFile = Get-Content myLogFile.log # or whatever file format, it's an input arg anyway 
for ($I = 0; $I -le $logFile.GetUpperBound(""); $I++) 
{ 
    $logFile[$I] # reads the line; you can assign a variable at this point 
} 

foreach循環也可以工作。我個人喜歡用,但foreach實際上是一樣的。相當於這樣的foreach:

foreach ($line in $logFile) 
{ 
    $line # perform whatever split operations you want to perform 
} 

請讓我們知道它是否工作!

+0

我已將上面的答案標記爲解決最初的問題。 :-) 但是,在針對幾個不同的日誌文件嘗試此解決方案時,我發現有些日誌文件在每行上都沒有時間戳,這會導致問題。 我應該問一個單獨的問題概述問題? – 2014-09-22 14:48:16

+0

我會看看如果我能弄清楚如何在這裏真正快速地向您發送代碼。我想出了一種方法,你可以用 – PSGuy 2014-09-24 05:18:31

+0

來做這件事。如果你有Dropbox(或類似的文件共享選項),你可以隨時把代碼放在一個txt文件中,可能在公共文件夾中,並提供**複製公共鏈接... **網址。這是我以前在論壇沒有直接上傳代碼/文件的方式時使用的一種方法。 – 2014-09-24 09:32:54

相關問題