2017-07-01 18 views
2

私はPowershellスクリプトを持っています。私はファイル内の各行を解析し、再フォーマットし、新しい文字列を出力ファイルに書き出します。数百行の入力ファイルでうまく動作します。しかし、最終的に数百万行のファイルに対して実行する必要があります。私は数時間待っていますが、それでもまだ完了していません。 this postに続いて、私はループの外にWrite-Outputを置く必要があると思いますが、これまでには失敗しました。Powershellの出力ファイルに書き込む方が効率的な方法が必要です

Foreach ($line in Get-Content $logFile) { 

    $arr = $line.Split() 

    $port1 = $arr[9].Split(":") 

    $port2 = $arr[11].Split(":") 

    $connstring = '|' + $port1[0] + "|" + $port1[1] + "|" + $port2[0] + "|" + $port2[1] + "|" + $arr[4] + "|" 

    Write-Output $connstring | Out-File "C:\logging\output\logout.txt" -Append 
} 

入力文字列の例は次のとおりです:

これが私の現在のコードです

06/14-04:40:11.371923 [**] [1:4:0] other [**] [Priority: 0] {TCP} 67.202.196.92:80 -> 192.168.1.105:55043 

そして、私はこれにそれを再フォーマットする必要があります。

|67.202.196.92|80|192.168.1.105|55043|other| 

すべてのヘルプ非常に高く評価されています!

+0

あなただけCAPTする必要がありますかIP /ポートとそれ以降のコンテンツを確認しますか?正規表現はあなたが望むものをより速く達成できるかもしれません。 – TheIncorrigible1

+0

はい、正しく入力してください。 IP、ポート、タグ(この場合は「other」)。 – yodish

答えて

3

Get-Content-ReadCountを使用すると、ファイル全体をメモリに読み込む必要がなく、一度に1行ずつファイルをストリーミングする効果があります。私はあなたのループの外で書き込み操作を移動する方が速いかもしれないと思います。ループ内の変数やステップが少なくても役立ちます。

Get-Content $logFile -ReadCount 1 | % { 
    '|' + (($_.Split()[9, 11, 4] -replace ':', '|') -join '|') + '|' 
} | Out-File "C:\logging\output\logout.txt" 
+0

ありがとうDave;これまでのところ、あなたのコードでの私の最初のテストは少し速いようですが、残念ながらそれほど多くはありません。元の投稿を、入力文字列と再フォーマットされた文字列の例で更新しました。おそらく私のコードロジックが微調整される必要がありますか? – yodish

+0

更新、このコードは大幅に高速でした。ありがとう、Dave! – yodish

1

このサンプルデータセットをテストするためにMeasure-Commandを使用してみてください、あなたの文字列の建設に

$connstring = "|$($port1[0])|$($port1[1])|$($port2[0])|$($port2[1])|$($arr[4])|" 

を追加を削除するかもしれないヘルプ。

1

はこのような何かを試してみてください:第四分割は、コロンが含まれていない後の要素(あなたが供給していないと、ファイルの一例)、その後、このようなものは、トリックを行う必要があると仮定すると

$test="06/14-04:40:11.371923 [**] [1:4:0] other [**] [Priority: 0] {TCP} 67.202.196.92:80 -> 192.168.1.105:55043" 

[email protected]" 
{Row:06/14-04:40:11.371923 [**] [1:4:0] {Text:other} [**] [Priority: 0] \{TCP\} {IPIN:67.202.196.92}:{PORTIN:80} -> {IPOUT:192.168.1.105}:{PORTOUT:55043}} 
"@ 

$test| ConvertFrom-String -TemplateContent $template |%{"|{0}|{1}|{2}|{3}|{4}|" -f $_.Row.IPIN, $_.Row.PORTIN, $_.Row.IPOUT , $_.Row.PORTOUT , $_.Row.Text } 

いますが、このようにcsvファイルにエクスポートすることができdireectly:

[email protected]" 
{Row:06/14-04:40:11.371923 [**] [1:4:0] {Text:other} [**] [Priority: 0] \{TCP\} {IPIN:67.202.196.92}:{PORTIN:80} -> {IPOUT:192.168.1.105}:{PORTOUT:55043}} 
"@ 

Get-Content $logFile | ConvertFrom-String -TemplateContent $template | % { 
[pscustomobject]@{ 
IPIN=$_.Row.IPIN 
PORTIN=$_.Row.PORTIN 
IPOUT=$_.Row.IPOUT 
PORTOUT=$_.Row.PORTOUT 
Text=$_.Row.Text 
} 

} | export-csv "C:\logging\output\logout.csv" -Append -NoType 
+1

2番目のコードでは、最後の行はforeachの代替語であり、IMOをコメントアウト/削除する必要があります。さもなければ+1私は 'ConvertFrom-String'がテンプレートで過小評価されていると思います – LotPings

関連する問題