2016-08-19 23 views
0

ログファイルからデータを抽出するスクリプトを作成します。検索クエリと実行時間の用語。ログファイルPowershellの正規表現でログファイルからデータを抽出する

19/08/2016 09:08:00 [100] ACTION%3DQuery%26MaxResults%3D9999%26abridged%3Dtrue%26abridgedmeta%3Ddatabase%26printfields%3DIM_DOCNUM,IM_VERSION%26combine%3Dfieldcheck%26databasematch%3DDATABASE_1,DATABASE-2%26Text%3D((pep21556)%3AIM_DOCNAME)%26fieldtext%3D(WILD%7BWORK%7D%3AIM_PRJ_SUBTYPE+AND+WILD%7BWEBDOC%7D%3AIM_CLASS)+AND+BIASDATE%7B1471612079e,2592000,20%7D%3Aautn_date+AND+BIASDATE%7B1471612079e,63072000,20%7D%3Aautn_date%26anyLanguage%3Dtrue%26TimeoutMS%3D60000 
19/08/2016 09:08:00 [100] Request completed in 12 ms. 
19/08/2016 09:08:28 [103] Request from 10.1.1.131 

ログファイルから

サンプルは、URLがエンコードされます。

進捗スクリプトでの私の仕事は、ログ・ファイルをロードし

foreach ($line in [System.IO.File]::ReadLines($filename)) 

その後、URLdecods各ラインと長いのSecurityInfo文字列を削除し

$VarURLDecoded = [System.Web.HttpUtility]::UrlDecode($line) -replace "SecurityInfo=.*" 

今、私は次のように抽出するために、正規表現に苦しんでいます:日+ Time、MaxResault = xxxxxxx、Text =((?????????):???????)、要求が次の行で完了するまでの時間(ミリ秒)。

$findText = $VarURLDecoded | select-string -Inputobject {$_} -pattern 

一部の正規表現があります。

'(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2})' will find 19/08/2016 09:08:00 
'MaxResults=(\d*)' will find MaxResults=9999 
'(?<Text>&Text=\(\([^()]*\)\:[^()]*\))' will find &Text=((campeau):IM_DOCNAME) 
'(\d* ms)' will find the xx ms 

しかし、2番目の行にある期間レコードを含むすべてのAND構文を結合することはできません。下の行に従うか、適切なタイムスタンプがあるという事実を使用してください。

基本正規表現が機能したら、名前付きグループを追加して結果をハッシュテーブルにエクスポートすることで、複雑さを増すことができます。

答えて

2

投稿されたログで判断すると、デコードする必要はありません。%xxエンコードされた文字がないためです。
テキスト処理の場合、[System.IO.File]のような低レベルのものは必要ありません。
追加のラインが必要ですので、-context before, afterパラメータを使用してください。

Name       Value 
----       ----- 
date       19/08/2016 
time       09:08:00 
duration      12 
results      9999 
text       ((pep21556):IM_DOCNAME) 

を代替的に、アカウントを取り込むのパターンマッチングの複雑なパターンに遅くなることがあり、文字列が選択、の使用と一致させ次のよう

$report = select-string -path $filename -context 0,1 -pattern (
    '^(?<date>.+?) ' + 
    '(?<time>.+?) .+?' + 
    '&MaxResults=(?<results>\d+).+?' + 
    '&Text=(?<text>[^&]+)') | 
%{ 
    $nextLine = $_.Context.PostContext[0] 
    $g = $_.matches[0].groups 
    @{ 
     date = $g['date'].value 
     time = $g['time'].value 
     results = $g['results'].value 
     text = $g['text'].value 
     duration = if ($nextLine -match 'completed in (\d+) ms') { $matches[1] } 
    } 
} 

$reportは今各オブジェクトの配列であります単純な文字列、?(別名Where-Object)のフィルタを使用して、結果を処理します。

$report = select-string -path $filename -context 0,1 -pattern '&MaxResults=' -simpleMatch | 
?{ $_.Line -match (
    '^(?<date>.+?) ' + 
    '(?<time>.+?) .+?' + 
    '&MaxResults=(?<results>\d+).+?' + 
    '&Text=(?<text>[^&]+)') 
} | %{ 
    $nextLine = $_.Context.PostContext[0] 
    $m = $matches # $matches is set by the above -match 
    @{ 
     date = $m['date'] 
     time = $m['time'] 
     results = $m['results'] 
     text = $m['text'] 
     duration = if ($nextLine -match 'completed in (\d+) ms') { $matches[1] } 
    } 
} 
+0

私の2番目の質問にお答えいただきありがとうございます。いくつかの点では、私が探しているファイルはそれぞれ約100メガバイトなので、[System.IO.File]を使うとパフォーマンスが向上すると思いました。元のデータはURLエンコードされています(デコードされたサンプルを記述して説明しやすくしています)。オリジナルのスクリプトにコードを適用しましたが、durationフィールドはbankです。 system.IO.File – user3019228

+0

:: ReadLinesの代わりにTried :: readAllTextを実行しました。スクリプトはもはや何も見つけられませんでしたので、ソリューションスクリプトでURLEncode行を処理するためにはどのような変更が必要ですか?(それぞれのファイルは約100メガ – user3019228

+1

'[IO.File] :: ReadAllLines($ filename)| select-string .....' – wOxxOm

関連する問題