【问题标题】:PowerShell Import-Csv Issue - Why is my output being treated as a single column and not a CSV?PowerShell Import-Csv 问题 - 为什么我的输出被视为单列而不是 CSV?
【发布时间】:2015-04-27 19:20:40
【问题描述】:

所以我有一个 CSV 文件,我需要对其进行一些操作,选择我需要的数据并导出到另一个 CSV 文件。

我的代码是:

$rawCSV = "C:\Files\raw.csv"
$outputCSV = "C:\Files\output.csv"

Import-Csv -Header @("a","b","c","d") -Path $rawCSV  |
select -Skip 7 |
Where-Object { $_.b.length -gt 1 } |
ft b,a,c,d |
Out-File $outputCSV

所以这段代码使用 Import-Csv 命令允许我只选择我需要的列,按我想要的顺序添加一些标题,然后我只是将输出放入一个名为 $outputCSV 的 CSV 文件中。此输出文件的内容如下所示:

b         a         c         d
-         -         -         -
john      smith     29        England
mary      poopins   79        Walton

我不确定此输出中的分隔符是什么,而不是将这些列视为单独的列,而是将它们视为一列。我继续使用以下代码用逗号替换所有空格:

$b = foreach ($line in $a)
{
    $fields = $line -split '`n'
    foreach ($field in $fields)
    {
        $field -replace " +",","
    }
}

这会产生一个如下所示的文件:

b,a,c,d
john,smith,29,England
mary,poppins,79,Walton

但这些仍然被视为一列,而不是我需要的四个单独的列。

* 更新 *

使用@给出的答案,我现在得到一个如下所示的文件:

【问题讨论】:

  • 输出看起来像 csv 格式,你在哪个程序中查看说它是一列的输出?
  • 如果我在 Excel 或 SQL 表中查看输出,它将显示为一列。
  • 如果我保存您的示例输出并在 excel 中打开它,我会看到预期的 4 列
  • 我知道。例如,如果我在写字板中打开文件,复制所有数据并粘贴到 excel 中,我会看到预期的四列。但是直接在Excel中打开文件,我看到一列...我认为这与Import-Csv命令在处理过程中意外处理数据有关...
  • 您可以查看文件中是否有任何非打印字符可能会造成混淆 -windowsitpro.com/powershell/get-hex-dumps-files-powershell

标签: powershell csv


【解决方案1】:

不要使用ft 重新排列您的列 - 它旨在格式化屏幕输出,并不适合 CSV。

“手动”解决方案:

$rawCSV = "C:\Files\raw.csv"
$outputCSV = "C:\Files\output.csv"

# Import and filter your raw data
$RawData = Import-Csv -Header @("a","b","c","d") -Path $rawCSV  
$Data    = $RawData | Select -Skip 7 | Where-Object { $_.b.length -gt 1 }

# Write your headers to the output file
"b","a","c","d" -join ',' | Out-File $outputCSV -Force

$ReorderedData = foreach($Row in $Data){
    # Reorder the columns in each row 
    '{0},{1},{2},{3}' -f $Row.b , $Row.a , $Row.c, $Row.d
}

# Write the reordered rows to the output file
$ReorderedData | Out-File $outputCSV -Append

使用Export-Csv:

从 PowerShell 3.0 开始,您还可以将行推送到 [pscustomobject] 并将其通过管道传输到 Export-Csvpscustomobject 保留您提供属性的顺序):

$rawCSV = "C:\Files\raw.csv"
$outputCSV = "C:\Files\output.csv"

# Import and filter your raw data
$RawData = Import-Csv -Header @("a","b","c","d") -Path $rawCSV  
$Data    = $RawData | Select -Skip 7 | Where-Object { $_.b.length -gt 1 }

# Take the columns you're interested in, put them into new custom objects and export to CSV
$Data | ForEach-Object { 
    [pscustomobject]@{ "b" = $_.b; "a" = $_.a; "c" = $_.c; "d" = $_.d } 
} | Export-Csv -NoTypeInformation $outputCSV

Export-Csv 将负责将字符串括在引号中以正确转义 ','(您不必担心一件事)

【讨论】:

  • 感谢您的回答。我在上面的 UPDATE 中上传了您的代码给出的输出图像。
  • @Johnathan 是的,很抱歉,忘记将标题写为单个字符串。请查看更新。我还使用Export-Csv 提供了一个更安全的替代方案
  • @Johnathan 请注意,要让 Excel 正确打开 CSV,您需要导出 CSV,并将分隔符设置为系统区域设置中定义的列表分隔符。
  • @Johnathan ++ Ansger 所说的,否则您需要使用 Excel 中的数据导入向导配置导入设置
  • @Mathias 您建议的“手动解决方案”仍然将列视为一列而不是四列,我不确定为什么会这样。但是,“Export-Csv”解决方案对我很有用,所以谢谢。 Ansgar,谢谢,我会确保这样做:)
【解决方案2】:

首先,您的原始 CSV 文件是什么样的?如果已经是这样了

john,smith,29,England
mary,poppins,79,Walton

然后import-csv 将为您提供一组您可以轻松操作的对象(对象是使用 PowerShell 的主要原因;)。例如,要检查导入后的内容:

$r = Import-Csv -Path $rawCSV -Header @("b","a","c","d") 
$r.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                              
-------- -------- ----                                     --------                                                                                                              
True     True     Object[]                                 System.Array

$r[0] | get-member

TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition                    
----        ----------   ----------                    
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()             
GetType     Method       type GetType()                
ToString    Method       string ToString()             
a           NoteProperty System.String a=smith         
b           NoteProperty System.String b=john          
c           NoteProperty System.String c=29            
d           NoteProperty System.String d=England

现在,您拥有属性名为“a”、“b”、“c”、“d”的对象数组。要操作您有select-object cmdlet 的对象:

$r | Select-Object a,b,c,d

a         b        c        d                                          
-         -        -        -                                          
smith   john       29    England                                    
poppins mary       79    Walton  

毕竟使用export-csv来设置输出文件:

$r | where { $_.b.length -gt 1 } | 
 select a,b,c,d | 
 Export-Csv -NoTypeInformation -Encoding utf8 -path $outputCSV

我可以想到将您的数据整理成一列的两个可能原因:

  1. 消费应用程序期望不同的编码,但找不到 分隔符
  2. 分隔符不是逗号,而是别的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 2023-03-05
    • 2018-10-17
    • 2019-06-14
    • 2019-11-02
    • 2021-04-12
    相关资源
    最近更新 更多