2017-02-24 8 views
1

PowershellをRegexパターンで使用して、そのパターンの出現をテキストファイルに数えます。その発生は、1行または複数行にわたって繰り返すことができます。Regexの出現数をカウントしてCSVに出力する

出力は、カウント付きのヒストグラムでなければなりません。 Powershell, Counting string ocurrences in a text fileを使用して

私はこの仕事を得ることができたが、それは唯一の行ごとに動作します実現(例えば一致が見つかった場合には1をカウントが、ライン上の複数の発生がある場合、これは正しくない)

ソースは、次のようになります。この

Lorem Ipsum Lorem Ipsum Ipsum user:john 
Lorem Ipsum user:peter 
Lorem Ipsum Lorem Ipsum user:george 
Lorem Ipsum user:john user:john user: john user:johnasddaasd user:john 
Lorem Ipsum vLorem Ipsum user: george 
Lorem Ipsum user:john 
私は現在、行ごとに取り組んでいるスクリプト持っ

- ではなく、複数の一致がライン上にある上記の例を

function GetUserCounts($fileName) 
{ 
    $msgCounts = @{} 

    switch -regex -file $fileName 
    { 
    '\buser:([a-zA-Z]+)\b' { 
     $msgType = $matches[1] 
     $msgCounts[$msgType] = [int]$msgCounts[$msgType] + 1 
    } 
    } 

    $msgCounts.GetEnumerator() | select Name,Value 
} 

$currentDate = (Get-Date -Format "yyyy-MM-dd HH:mm:ss") 

$inputFile=$args[0] 

GetUserCounts $inputFile | Export-Csv .\counts.csv -NoTypeInformation 

import-csv .\counts.csv | 
Select-Object *,@{Name='Filename';Expression={$inputFile}},@{Name='Rundate';Expression={$currentDate}} | 
export-csv msgCounts.csv -NoTypeInformation 
Remove-Item .\counts.csv 

誰かがこの例題をテキストファイルのどこかで扱えるよう手助けできますか?

UPDATE 出力は、各スイッチケース内に別のテストを行う必要があるでしょう

Name , Count 
john, 6 
peter, 1 
george, 2 
+0

正規表現に複数行のスイッチを使用し、ファイル全体をフィードする – 4c74356b41

+0

私はこれらの行に沿って考えていましたが、文字列を見つけるためにスイッチを使用しているので、スクリプトのロジックが間違っていると思います。全体を見て – Rob

+0

次に 'switch'を使わないでください:-) –

答えて

2

ようになります。これを行う簡単な方法は、単純に文字列を分割し、その結果をカウントしている - 1:

switch -regex -file $fileName 
{ 
    '\buser:([a-zA-Z]+)\b' { 
    $msgType = $matches[1] 
    $msgCount = ($_ -split [regex]::Escape($msgType)).Count - 1 
    [int]$msgCounts[$msgType] += $msgCount 
    } 
} 

または得Matchesから捕捉基上-AllMatchesパラメータスイッチ群とSelect-Stringを使用:

(Select-String -Path .\test.txt '\buser:([a-zA-Z]+)\b' -AllMatches).Matches |ForEach-Object { 
    $_.Groups[1].Value 
} |Group -NoElement 

ユーザー名の前に空白を入れたい場合は、パターンを'\buser:\s?([a-zA-Z]+)\b'に変更します。

+0

これはすべての出現にマッチしますが、マッチによってグループ化されていません。 – Rob

+0

@Rob updated answer –

+1

最初のアプローチに関して、分割する代わりにすべての一致を返す '[regex] :: matches'を使うことができます。 – wOxxOm

関連する問題