PowerShell导入Csv问题-为什么我的输出被视为单个列而不是Csv?

PowerShell导入Csv问题-为什么我的输出被视为单个列而不是Csv?,powershell,csv,Powershell,Csv,所以我有一个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 $o

所以我有一个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命令,允许我只选择所需的列,按所需顺序添加一些标题,然后将输出放入名为$outputcv的Csv文件中。此输出文件的内容如下所示:

b         a         c         d
-         -         -         -
john      smith     29        England
mary      poopins   79        Walton
b,a,c,d
john,smith,29,England
mary,poppins,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      poopins   79        Walton
b,a,c,d
john,smith,29,England
mary,poppins,79,Walton
但这些仍然被视为一列,而不是我需要的四列

*更新*

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

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

不要使用
ft
对列进行重新排序-它旨在为屏幕设置输出格式,而不是真正适用于CSV

“手动”解决方案:
使用
导出Csv
: 从PowerShell 3.0开始,您还可以将行推送到
[pscustomobject]
中,并将其输送到
导出Csv
pscustomobject
保留您提供属性的顺序):


Export Csv
将注意用引号将字符串括起来,以便正确地转义“,”(您不必担心一件事)

不要使用
ft
对列进行重新排序-它旨在为屏幕设置输出格式,而不是真正适合Csv

“手动”解决方案:
使用
导出Csv
: 从PowerShell 3.0开始,您还可以将行推送到
[pscustomobject]
中,并将其输送到
导出Csv
pscustomobject
保留您提供属性的顺序):


导出Csv
将处理用引号括起来的字符串,以正确地转义“,”(您不必担心一件事)

首先,您的原始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  
然后使用
导出csv
设置输出文件:

$r | where { $_.b.length -gt 1 } | 
 select a,b,c,d | 
 Export-Csv -NoTypeInformation -Encoding utf8 -path $outputCSV
我可以想到两个可能的原因,为什么你的数据被测试为一列:

  • 正在使用的应用程序需要不同的编码,但找不到 分隔符
  • 分隔符不是逗号,而是其他东西

  • 首先,您的原始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  
    
    然后使用
    导出csv
    设置输出文件:

    $r | where { $_.b.length -gt 1 } | 
     select a,b,c,d | 
     Export-Csv -NoTypeInformation -Encoding utf8 -path $outputCSV
    
    我可以想到两个可能的原因,为什么你的数据被测试为一列:

  • 正在使用的应用程序需要不同的编码,但找不到 分隔符
  • 分隔符不是逗号,而是其他东西


  • 输出看起来像csv格式,您在哪个程序中查看的输出显示为一列?如果我在Excel或SQL表格中查看输出,它将显示为一列。如果我保存示例输出并在Excel中打开它,我将看到预期的4列。例如,如果我在写字板中打开文件,复制所有数据并粘贴到excel中,我会看到预期的四列。但是直接在Excel中打开文件,我看到一列。。。我认为这与
    Import Csv
    命令在处理过程中意外处理数据有关…您可以查看文件中是否存在任何可能会混淆的非打印字符-输出看起来像Csv格式,您在哪个程序中查看的输出显示为一列?如果我在Excel或SQL表中查看输出,它将显示为一列。如果我保存您的示例输出并在Excel中打开它,我将看到预期的4列。例如,如果我在写字板中打开文件,复制所有数据并粘贴到excel中,我会看到预期的四列。但是直接在Excel中打开文件,我看到一列。。。我认为这与
    Import Csv
    命令在处理过程中意外地处理数据有关…您可以查看文件中是否有任何非打印字符,这可能会让您感到困惑-感谢您的回答。我在上面的更新中上传了您的代码输出的图像。@Johnathan是的,很抱歉,忘记将标题作为单个字符串写入。请查看更新。我还提供了一个更安全的选择,使用
    导出Csv
    @Johnathan注意,要让Excel正确打开Csv,您需要导出Csv,并将分隔符设置为系统区域设置中定义的列表分隔符。@Johnathan++Ansger说,否则,您需要使用中的数据导入向导配置导入设置Excel@Mathias您建议的“手动解决方案”仍然将列视为一列而不是四列,我不确定这是为什么。然而,“导出Csv”解决方案对我来说非常有用,所以谢谢你。Ansgar,谢谢,我会确保做到的:)谢谢你的回答。我在上面的更新中上传了您的代码输出的图像。@Johnathan是的,很抱歉,忘记将标题作为单个字符串写入。请查看更新。我还包括了一个更安全的选择,使用
    导出Csv
    @Johnathan注意,对于Excel