2017-05-29 1 views
0

いくつかのフィールドに新しい行が埋め込まれた大きなCSVファイルがあります。新しい行が埋め込まれたフィールドを持つ行を含むCSVをインポートすると、Excel 2016でエラーが発生します。これは、powershellのオブジェクトのすべてのプロパティのテキストを置き換える最善の方法ですか?

this postに基づいて、任意のフィールドの新しい行をスペースで置き換えるコードを書いています。以下は、機能と問題を複製するコードブロックです。オプション1が動作します。コメントアウトされているオプション2は、オブジェクトを文字列にキャストします。私は、オプション2がより速く動くことを望んでいました。

質問:非常に大きなファイルを処理するパフォーマンスを最適化するためのよりよい方法がありますか?

$array = @([PSCustomObject]@{"ID"="1"; "Name"="Joe`nSmith"}, 
      [PSCustomObject]@{"ID"="2"; "Name"="Jasmine Baker"}) 

$array = $array | ForEach-Object { 
    #Option 1: produces an Object, but is code optimized? 
    foreach ($n in $_.PSObject.Properties.Name) { 
     $_.PSObject.Properties[$n].Value = ` 
      $_.PSObject.Properties[$n].Value -replace "`n"," " 
    } 

    #Option 2: produces a string, not an object 
    #$_ = $_ -replace "`n"," " 

    $_ 
} 

私の実際の使用の場合には、各行は> 15個のフィールドがあり、それらの任意の組み合わせが埋め込まれた1つの以上の新しい行を有することができることに注意してください。

+0

私はforeachのはをForEach-Objectに比べて高速であることをどこかで読ん続いているよりもはるかに高速です。 ストップウォッチクラスで言及した両方のシナリオのテストを行うことができます。そのようにそれを活用する: $ resultstime =新しいタイムスパン-Minutes 1 $ resultstime = [diagnostics.stopwatch] :: StartNew() $ resultstime.Elapsed それは –

+0

おかげマーティン:)を停止することを忘れないでください。私はストップウォッチクラスを使用して、@ wOxxOmからの提案と比較して私の元のコードの時間を使います。 –

+0

あなたの所見を共有してください:) –

答えて

0
  • 、プロセスを読み込み、ファイル(PowerShellの3+)からCSVを構築するために、高速TextFieldParserを使用します。

    [Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') >$null 
    $parser = New-Object Microsoft.VisualBasic.FileIO.TextFieldParser 'r:\1.csv' 
    $parser.SetDelimiters(',') 
    $header = $parser.ReadFields() 
    
    $CSV = while (!$parser.EndOfData) { 
        $i = 0 
        $row = [ordered]@{} 
        foreach ($field in $parser.ReadFields()) { 
         $row[$header[$i++]] = $field.replace("`n", ' ') 
        } 
        [PSCustomObject]$row 
    } 
    
  • それとも既存のでインプレース各フィールドを変更CSV配列:

    foreach ($row in $CSV) { 
        foreach ($field in $row.PSObject.Properties) { 
         $field.value = $field.value.replace("`n", ' ') 
        } 
    } 
    

注:

  1. foreach声明は(もforeachとしてエイリアス)ForEach-Objectへの配管
  2. $stringVariable.replace()が速く-replaceオペレータ
+0

詳細な返信をありがとう。私はこれらのアプローチの両方を試し、より速いものを見てみましょう。 –

+0

foreachはForeach-Objectよりもはるかに高速です。 replaceループはForEach-Objectで36秒、foreachループで11秒しかかかりません。 –

+0

私はまた、オブジェクトに対して-replaceを使うことをあきらめます。結果は文字列に変換されるようです。週2回のスクリプトでは11秒で十分です。 –

関連する問題