2016-08-18 13 views
0

非常に大きな.txtファイルを読み込み、特定の行を選択してCSVに入れるpowershellコードを書きました。問題は、ファイルは次のようにフォーマットされていることである。テキストファイルをCSVファイルに変換する

header1: Data1 
header2: Data1 
header3: Data1 
header4: Data1 
header1: Data2 
header2: Data2 
header3: Data2 
header4: Data2 

と私はこれに変換する必要があります。

Header1,Header2,Header3,Header4 
data1,data1,data1,data1 
data2,data2,data2,data2 

をコードはこれです:

$path = get-location 
    $textfile = Get-FileName $env:USERPROFILE\Downloads\ 


    $writefile = "$path\data2.csv" 
    $reader = [System.IO.File]::OpenText($textfile) 
    $writer = New-Object System.IO.StreamWriter $writefile 
    $writer.WriteLine('{0},{1},{2},{3}', "Policy","Schedule Type","Retention Level","Host") 

     for(;;) { 

       $line = $reader.ReadLine() # 
       if ($null -eq $line) { 
       break 
       } 

       $data = $line.Split(":") 

       if ($null -ne $data[0]) { 
       $newdata0 = $data[0].trimstart(" ") 
       } 
       if ($null -ne $data[1]) { 
       $newdata1 = $data[1].trimstart(" ") 
       } 

       if ($newdata0 -eq "Policy") {$writer.WriteLine('{0},{1},{2},{3}', $newdata1,$null,$null,$null)} 

       if ($newdata0 -eq "Schedule Type") {$writer.WriteLine('{0},{1},{2},{3}', $null,$newdata1,$null,$null)} 

       if ($newdata0 -eq "Retention Level") {$writer.WriteLine('{0},{1},{2},{3}', $null,$null,$newdata1,$null)} 

       if ($newdata0 -eq "Host") {$writer.WriteLine('{0},{1},{2},{3}', $null,$null,$null,$newdata1)}  

      } 



    $reader.Close() 
    $writer.Close() 

しかし、私は終わります(実際のデータ):

Policy,Schedule Type,Retention Level,Host 
FS-Win-Servers-Tokyo-DACS_ONLY,,, 
,FULL (0),, 
,,infinity (9), 
,,,opback03e.options-it.com 
DB-Win-Exch2013-ADB11,,, 
,INCR (1),, 
,,6 months (6), 
,,,opback03e.options-it.com 
DB-Win-Exch2013-MDB11,,, 
,INCR (1),, 
,,6 months (6), 
,,,opback03e.options-it.com 
DB-Win-Exch2013-MDB10,,, 
,INCR (1),, 
,,6 months (6), 
,,,opback03e.options-it.com 

私はこのコードが間違っていると思いますか、あるいは単にCSVを再フォーマットする方法を見つける必要がありますか?

+0

私は、これはあなたを助けると思う:http://stackoverflow.com/a/8970351/5341953 – notgiorgi

+0

感謝が、私はCSVファイルを持っています。問題は私のコードでは、私はCSVの1行に書き込むためのデータを取得することはできません。それは正しい列に書き込みますが、私は同じ行にデータを取得する方法を知っています。 – user2026188

答えて

0

あなたの問題は、$ writer.WriteLineを呼び出すたびに、書き込み先のファイルの行を進めていることです。あなたは、各ループ上の情報を収集する必要がありますが、これだけはうまくいくかもしれない、一回第4回ループを書く:

$loopCounter = 0 

    for(;;) { 

      $line = $reader.ReadLine() # 
      if ($null -eq $line) { 
      break 
      } 

      $data = $line.Split(":") 

      if ($null -ne $data[0]) { 
      $newdata0 = $data[0].trimstart(" ") 
      } 
      if ($null -ne $data[1]) { 
      $newdata1 = $data[1].trimstart(" ") 
      } 

      if ($newdata0 -eq "Policy") {$data1=$newdata} 

      if ($newdata0 -eq "Schedule Type") {$data2=$newdata} 

      if ($newdata0 -eq "Retention Level") {$data3=$newdata} 

      if ($newdata0 -eq "Host") {$data4=$newdata}  


      if (($loopCounter % 4) -eq 3) {$writer.WriteLine('{0},{1},{2},{3}', $data1, $data2, $data3, $data4)}   

      $loopCounter++ 

     } 
+0

iveはもう少し編集をしましたが、これは私が必要とするコンセプトです!どうもありがとう!非常に感謝しています。 – user2026188

0

私はレコードの区切り文字(行末を置き換える)として機能するために何かを繰り返し探したいと思うだろう。

$header = New-Object System.Collections.Generic.List[String] 
Get-Content test.txt | Where-Object { $_ -match '(?<Header>[^:]+): *(?<Value>.+)$' } | ForEach-Object { 
    if ($header.Contains($matches.Header)) { 
     # End of record start again. 
     $header.Clear() 
     # Output 
     $psObject 
    } 
    if ($header.Count -eq 0) { 
     # Start of the record. Create an object to hold it. 
     $psObject = New-Object PSObject 
    } 

    # Add the current header and value to the object. 
    $psObject | Add-Member $matches.Header $matches.Value 
    # Add the header name to the record controller 
    $header.Add($matches.Header)  
} 
# Output the last entry from the file (no end detection) 
$psObject 
+0

こんにちは、私は$ data = $ line.Split( ":")でそれをやっていました。あなたのコードを実行しても、ヘッダ:dataのような行のデータはまだフォーマットされていますが、リストの下に)、行の代わりに行にデータを広げます。 – user2026188

+0

申し訳ありませんが、あなたは私を失ってしまった。これは、垂直方向に配置されたデータセットを、各ヘッダー値に基づいたプロパティを持つPSObjectsのセットに変換します。これはPSObjectの配列なので、出力することはできますが(パーサーが動作していれば)適合していることがわかります。フォーマットを適用するかエクスポートするだけです。例えば'Export-Csv'や' Format-Table'や 'ConvertTo-Csv'などがあります。 –

+0

申し訳ありませんが、誤解、誤解。私はコードを再実行し、CSVにエクスポートしました。それは水平に送信しますが、ヘッダーは一致しないので、垂直方向ではなく水平方向に繰り返されます。 – user2026188

関連する問題