多个csv文件到一个csv文件 - Powershell

时间:2017-01-22 18:21:23

标签: powershell csv merge

我一直在阅读以前关于这个概念的一些帖子,但我发现所有的解决方案都与彼此截然不同。

我有多个csv分布在单独的文件夹上(所有文件都有相同的路径,但子文件夹不同)。

我现在需要导入这些csv,更改标题并将其导出到一个单独的csv中。

我一直在尝试这个但是我得到一个非常奇怪的错误:Import-Csv:无法打开文件" C:\ Windows \ system32 \ Book1.csv" 虽然我的路径是指C:\ csv?

$CSVFolder = 'C:\csv\';
$OutputFile = 'C:\export\test3.csv';

$CSV= @();

Get-ChildItem -Path $CSVFolder -Filter *.csv | ForEach-Object { 
    $CSV += @(Import-Csv -Path $_)
}

$CSV | Export-Csv -Path $OutputFile -NoTypeInformation -Force;

我正在考虑使用数据表作为标题,但此时我不太清楚。此错误的问题对我来说也不明确......

3 个答案:

答案 0 :(得分:1)

正如已经指出的那样:

  • Import-Csv -Path $_代码中应为Import-Csv -Path $_.FullName

    • (严格来说,它应该是Import-Csv -LiteralPath $_.FullName,因为传递给-Path参数的字符串需要通配符解析。)
  • 因为表示[System.IO.FileInfo]返回的文件的 Get-ChildItem实例在传递给-Path时会转换为字符串(或-LiteralPath)参数作为命令行参数 (而不是通过管道),在这种情况下 仅仅是文件名Get-ChildItem命令以目录为目标,则使用完整路径 (参见下面的背景信息)。

    • 仅将Book1.csv这样的文件名解释为相对于当前目录(在您的情况下恰好为C:\Windows\system32),因此{{1查找文件Import-Csv而非预期的C:\Windows\system32\Book1.csv

    • 请注意,管道 C:\csv\Book1.csv输出到cmdlet通常受此影响,因为Get-ChildItem属性(PowerShell添加)在幕后)包含完整路径(包括PS提供商前缀)绑定到.PSPath参数 请注意,从PSv5.1.14393.693开始,由于存在错误,-LiteralPath的此机制已损坏

这是每当Import-Csv个实例传递给通过[System.IO.FileInfo]( - array)-typed参数作为参数接受文件路径的cmdlet时出现的常见错误

为了安全起见:[string]收到的对象作为参数值 传递给另一个命令时,始终使用.FullName(而不是通过管道)确保通过完整路径。

可选背景信息:

这种行为是一个陷阱,因为假设将Get-ChildItem实例 as as is is is is is is is is is is is is is is is is is is is is is 以接受文件路径的工作是完全合理的,给定PowerShell的面向对象特性 - 特别是,因为 在使用管道而不是参数值时可以正常工作。

不幸的是,接受文件路径([System.IO.FileInfo]-Path参数)的内置cmdlet仅作为-LiteralPath执行(没有接受{{1}的参数集}实例直接),并且在[string]到 - 字符串转换的过程中出现了问题。

如果[System.IO.FileInfo]实例始终如一地评估文件,那么也不会有问题。 完整路径,遗憾的是不是这样:

  • [System.IO.FileInfo]输出[System.IO.FileInfo]个实例,这些实例仅在字符串上下文中评估文件名

  • Get-ChildItem <directory>输出评估为完整路径的[System.IO.FileInfo]个实例

换句话说:只有当Get-ChildItem <literalFilePathOrWildCardExpr>目录(文件夹)定位时,它返回的对象才会在字符串中评估其文件名称上下文。
相比之下,定位特定文件或使用通配符表达式会产生完整路径;使用[System.IO.FileInfo]时,情况总是如此。

答案 1 :(得分:0)

你只需要&#39;全名&#39;财产,而不是&#39; name&#39;。

例如:

PS /Users/adil/Downloads> gi *csv |select name                                                                  

Name              
----              
tradesdownload.csv


PS /Users/adil/Downloads> gi *csv |select name, fullname                                                                

Name               FullName                                
----               --------                                
tradesdownload.csv /Users/adil/Downloads/tradesdownload.csv

答案 2 :(得分:0)

试试这段代码。此代码获取所有csv文件,导入它们并仅获取第1,2,3列,并将列名更改为header1,header2,header3,然后将所有文件导出到新的csv文件中

Get-ChildItem "C:\temp2" -Filter "*.csv" | 
    %{Import-Csv $_.FullName -Header header1, header3,header4} | 
                    Export-Csv "c:\temp\result.csv" -NoTypeInformation


#a short version (for no purist)
gci "C:\temp2" -Filter "*.csv" | %{ipcsv $_.FullName -Header header1, header3,header4} | epcsv "c:\temp\result.csv" -NoType