

CSVファイルを読み込み、半角スペースを消して出力したいと考えています。

**元データ:**

[code]

    1111     ,test2    ,test3   ,test4    
    111     ,test2    ,test3   ,test4    
    11     ,test2    ,test3   ,test4
    
[/code]

**期待する結果:**

[code]

    1111,test2,test3,test4
    111,test2,test3,test4
    11,test2,test3,test4
    
[/code]

CSVの各要素の半角スペースをTrimするため、PowerShellで次のようなコードを書いたのですが、出力されたCSVが`$results`のlengthになってしまいます。

解決策等ないでしょうか。

[code]

    $clms =@("col1","col2","col3","col4");
    
    $products = Import-Csv 'C:\test\input.csv' -Header $clms -Encoding Default
    $results = @()
    
    foreach ($product in $products){
     $line  = @()
        foreach ($clm in $clms) {
            $line += $product.$clm.Trim()
        }
     $results += $line
    }
    
    $results | Export-Csv -Encoding Default -NoTypeInformation 'C:\test\output.csv'
    
[/code]


CC BY-SA 4.0
2022-07-07T06:03:01.807
89801
2023-12-03T06:08:06.000
2023-10-27T08:34:02.403
3060
53144
question
powershell
PowerShellでCSVから読み込んだ各要素を加工し、CSVで出力


読み込んだデータを変更して保存すれば良いと思います。

[code]

    $clms =@("col1","col2","col3","col4");
    
    $products = Import-Csv 'input.csv' -Header $clms -Encoding Default
    $results = @()
    
    foreach ($product in $products){
      foreach ($clm in $clms) {
        $product.$clm= $product.$clm.Trim()
      }
    }
    
    $products | Export-Csv -Encoding Default -NoTypeInformation 'output.csv'
    
[/code]

input.csv

> 1111 ,test2 ,test3 ,test4  
>  111 ,test2 ,test3 ,test4  
>  11 ,test2 ,test3 ,test4

output.csv

> "col1","col2","col3","col4"  
>  "1111","test2","test3","test4"  
>  "111","test2","test3","test4"  
>  "11","test2","test3","test4"


CC BY-SA 4.0
2022-07-07T08:29:03.183
89806
2022-07-07T08:29:03.183
39819
89801
answer


「出力されたCSVが`$results`のlengthになってしまいます。」についてはこちらの記事が関連するようですね。  
`Export-Csv`が出力する対象のデータが違うようです。  
[Export-CSV exports length but not
name](https://stackoverflow.com/q/19450616/9014308)

> `Export-Csv` exports a table of object properties and their values. Since
> your script is producing string objects, and the only property they have is
> length, that's what you got.
>
> If you just want to save the list, use `Out-File` or `Set-Content` instead
> of `Export-Csv`.

> Export-Csvは、オブジェクトのプロパティとその値のテーブルをエクスポートします。
> スクリプトは文字列オブジェクトを生成しており、それらが持つ唯一のプロパティは長さであるため、それが得られます。
>
> リストを保存するだけの場合は、Export-Csvの代わりにOut-FileまたはSet-Contentを使用します。

それから、`$line += $product.$clm.Trim()`や`$results +=
$line`の処理だと1行の中の各列のデータが分離されてそれぞれ1行のデータに分かれてしまいます。  
`$results += $line`の際に[about_Join](https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.core/about/about_join?view=powershell-7.2)でカンマで連結しておく必要があるでしょう。

対策としては以下のように2行を変更します。`####`でコメントした部分が変更点です。

[code]

    $clms =@("col1","col2","col3","col4");
    
    $products = Import-Csv 'C:\test\input.csv' -Header $clms -Encoding Default
    $results = @()
    
    foreach ($product in $products){
     $line  = @()
        foreach ($clm in $clms) {
            $line += $product.$clm.Trim()
        }
     $results += $line -join ',' #### 接続しておかないとすべてが各行に分かれて格納される
    }
    
    $results | Out-File -Encoding Default 'C:\test\output.csv' #### Export-CsvではなくOut-File
    
[/code]


CC BY-SA 4.0
2022-07-07T10:16:43.150
89810
2022-07-07T10:16:43.150
26370
89801
answer


CSVとして扱う必要があるのか気になりました。単なるテキストファイルとして扱い、`,`の前の空白の削除ではダメですか？

[code]

    Get-Content C:\test\input.csv -Encoding Default |
      ForEach-Object { $_ -replace ' ,', ',' } |
      Set-Content C:\test\output.csv -Encoding Default
    
[/code]


CC BY-SA 4.0
2022-07-07T19:48:15.460
89819
2022-07-07T19:48:15.460
4236
89801
answer