【问题标题】:Export csv via pscustomobject displaying incorrectly powershell通过 pscustomobject 导出 csv,powershell 显示不正确
【发布时间】:2019-03-18 10:49:40
【问题描述】:

我有以下代码:

    function realtest
    {
         $files = Get-ChildItem -Path 'D:\data\' -Filter *.csv
         $tester = [PSCustomObject]@{

         foreach ($file in $files)
         {
             $tempName = $file.BaseName
             $temp = Import-Csv $file
             $tester | Add-Member -MemberType NoteProperty -Name $tempName -Value $temp.$tempName
         }
         $tester
         $tester | Export-Csv "D:\result.csv" -NoTypeInformation
    }

我正在尝试将一堆数据导出到 CSV,但是当它在 csv 上显示数据时,如下所示

"E0798T102","E0798T103"
"System.Object[]","System.Object[]"

但是当我在控制台上打印时它显示如下

E0798T102       E0798T103
---------       ---------
{0, 0, 0, 0...} {0, 0, 0, 0...}

最终,我希望 E0798T102 和 E0798T103 在 result.csv 中作为单独的列

请注意,我将循环遍历 50 个 csv,每个都应显示为自己的列

【问题讨论】:

  • 根据您的代码,似乎每个 CSV 文件都将每个文件的基本名称作为第一个也是唯一一个只有一行数据的列标题。它是否正确?或者每个 CSV 文件是否仅包含一列以文件基名称作为标题和许多行,您最终需要一个包含 50 列不同行数的 CSV 文件?
  • 是的,这是正确的,但每个 csv 文件中只有一列包含 500 行数据

标签: arrays powershell csv export-to-csv


【解决方案1】:

对于您的问题,这是一个非常低效的答案。如果保持原样,则假定您的 CSV 文件已经有一个带有 CSV 文件基名的标题:

$CSVs = Get-ChildItem -path 'D:\data\' -filter "*.csv" -file
$headers = $CSVs.basename
$table = [System.Data.DataTable]::new("Files")
foreach ($header in $headers) {
    $table.Columns.Add($header) | out-null
}
foreach ($CSV in $CSVs) {
    #$contents = Import-Csv $CSV -Header $CSV.basename # If CSV has no header
    $contents = Import-Csv $CSV # If CSV contains header
    $rowNumber = 0
    foreach ($line in $Contents) {
        $rowcount = $table.rows.count
        if ($rowNumber -ge $rowCount) {
            $row = $table.NewRow()
            $row[$CSV.basename] = $line.$($CSV.basename)
            $table.Rows.Add($row)

        }
        else {
            $row = $table.rows[$rowNumber]
            $row[$CSV.basename] = $line.$($CSV.basename)

        }

        $rowNumber++
    }
}
$table | Export-Csv output.csv -NoTypeInformation   

如果您的 CSV 文件没有标题,您可以取消注释已注释的 $contents 行。如果您取消注释第一个,您只需注释掉下一个 $contents 变量赋值。

【讨论】:

    【解决方案2】:

    根据您的 sn-p,这可以大大简化:

    function Get-Csv {
        $col = foreach ($file in Get-ChildItem -Path D:\data -Filter *.csv) {
            $csv = Import-Csv -Path $file.FullName
            [pscustomobject]@{
                $csv.($file.BaseName) = $csv
            }
        }
        $col | Export-Csv D:\result.csv -NoTypeInformation
    
        return $col
    }
    

    然而 文件似乎是错误的方法,因为您试图在标题下嵌入 对象。这实际上不适用于表格格式,因为您只能获得一层深度。您应该展开对象上的所有属性,或者使用可以表示深度的不同格式,例如

    格式问题的原因在于序列化的工作方式。您将获得对象的字符串表示形式。

    转换为 并不困难,您只需交换您的Export-Csv 电话:

    $col | ConvertTo-Json -Depth 100 | Out-File -FilePath D:\result.json
    

    注意:我指定 -Depth 100 是因为 cmdlet 的默认 Depth2

    【讨论】:

    • 您好,感谢您的回复。我正在尝试运行您的代码,但出现以下错误 Import-Csv : You must specify either the -Path or -LiteralPath parameters, but not both. At line:181 char:24 + $csv = $file | Import-Csv A null key is not allowed in a hash literal. At line:183 char:13 + $csv.($file.BaseName) = $csv
    • 我使用您编写的更新脚本再次重新运行它,这是我得到System.Object[] --------------- {@{E0798T102=0}, @{E0798T102=0}, @{E0798T102=0}, @{E0798T102=0}...} {@{E0798T103=0}, @{E0798T103=0}, @{E0798T103=0}, @{E0798T103=0}...} 的结果在csv文件中我得到以下System.Object[] System.Object[] System.Object[]
    • 感谢您的支持,但 AdminOfThings 刚刚做了一个完美运行的脚本。
    猜你喜欢
    • 2020-01-02
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2019-03-31
    相关资源
    最近更新 更多