【问题标题】:PowerShell copy and rename multiple .csv files from 10+ subfoldersPowerShell 从 10 多个子文件夹复制和重命名多个 .csv 文件
【发布时间】:2019-01-28 04:28:08
【问题描述】:

我正在寻找一种方法来复制多个名称完全相同、位于不同文件夹中的 .csv 文件(它们都在同一个目录中)并将它们合并到 1 个 .csv 文件中(我想跳过复制头的第一行,除了第一个文件,并且没有规则在每个 .csv 文件中写入多少行,因此脚本应该识别写入的行以知道合并的行数和合并/以避免空行)。

这是我迄今为止尝试过的:

$src = "C:\Users\E\Desktop\Merge\Input\Files*.csv"
$dst = "C:\Users\E\Desktop\Merge\Output"

Get-ChildItem -Path $src -Recurse -File | Copy-Item -Destination $dst

还有这个:

Get-ChildItem -Path $src -Recurse -File | Copy-Item -Destination $dst | 
ForEach-Object {
$NewName = $_.Name
$Destination = Join-Path -Path $_.Directory.FullName -ChildPath $NewName
Move-Item -Path $_.FullName -Destination $Destination -Force
}

有什么帮助吗? :)

【问题讨论】:

  • 所有这些 csv 文件都有相同的标题吗?如果是,您可以在循环中使用Import-CSV 来获取所有包含的数据,并将所有数据输出到一个带有Export-CSV 的单个csv 文件,使用参数-Append。
  • 是的,它们都有相同的标题。我目前正在努力解决:Get-Content:特定路径的对象不存在,或者已被 -Include 或 -Exclude 参数过滤。

标签: powershell csv merge copy


【解决方案1】:

由于您希望合并文件,您不妨将它们全部读入 PowerShell,然后一次输出整个内容。你可以这样做:

$Data = Get-ChildItem -Path $src -Recurse -File | Import-Csv
$Data | Export-Csv $dst\Output.csv -NoTypeInformation

如果您的 CSV 文件非常大,这可能不可行,但如果所有文件的标题行都相同,这是一种合并 CSV 文件的简单方法。

另一种方法是将其视为文本,这样占用的内存要少得多。为此,您需要获取文件列表,完整复制第一个文件,然后跳过标题行复制其余文件。

$Files = Get-ChildItem $src -Recurse
$TargetFile = Join-Path $dst $Files[0].Name
$Files[0] | Copy-Item -Dest $TargetFile
#Skip the first file, and loop through the rest
$Files | Select -Skip 1 | ForEach-Object{
    #Get the contents of the file, and skip the header row, then append the rest to the target
    Get-Content $_ | Select -Skip 1 | Add-Content $TargetFile
}

编辑:好的,我想复制这个过程,以便找出是什么给了你错误。为此,我创建了 3 个文件夹,并将包含 4 个条目的 .csv 文件复制到每个文件夹中,所有文件都名为“Files 06202018.csv”。我在上面运行了我的代码,它做了它应该做的事情,但是有一些文件损坏,第二个文件将直接附加到第一个文件的末尾而没有为其创建新行,所以我改变了一些事情,从复制第一个文件,读取它并在目标中创建一个新文件。下面的代码对我来说完美无缺:

$src = "C:\Temp\Test\Files*.csv" 
$dst = "C:\Temp\Test\Output"
$Files = Get-ChildItem $src -Recurse 
$TargetFile = Join-Path $dst $Files[0].Name
GC $Files[0] | Set-Content $TargetFile 
#Skip the first file, and loop through the rest 
$Files | Select -Skip 1 | ForEach-Object{ 
    #Get the contents of the file, and skip the header row, then append the rest to the target 
    Get-Content $_ | Select -Skip 1 | Add-Content $TargetFile 
}

拿走了文件:

C:\Temp\Test\Lapis\Files 06202018.csv
C:\Temp\Test\Malachite\Files 06202018.csv
C:\Temp\Test\Opal\Files 06202018.csv

并将这三个文件合并为一个正确合并的文件:

C:\Temp\Test\Output\Files 06202018.csv

我唯一遇到的问题是我在运行它之前忘记删除目标文件。根据这些文件的大小以及可用内存的大小,您可以通过将最后两行更改为以下代码来加快速度:

    Get-Content $_ | Select -Skip 1
} | Add-Content $TargetFile

这将读取所有文件(除了第一个文件)并且只写入一次目标,而不必获得文件锁定、打开文件进行写入、写入和关闭每个文件的目标。

【讨论】:

  • 感谢您的回复,我尝试这样合并:$src = "C:\Users\E\Desktop\Merge\Input\Files*.csv" $dst = "C:\Users\E\Desktop\Merge\Output" Get-ChildItem -Path $src -Recurse -File | Copy-Item -Destination $dst $Files = Get-ChildItem $src -Recurse $TargetFile = Join-Path $dst $Files[0].Name $Files[0] | Copy-Item -Dest $TargetFile #Skip the first file, and loop through the rest $Files | Select -Skip 1 | ForEach-Object{ #Get the contents of the file, and skip the header row, then append the rest to the target Get-Content $_ | Select -Skip 1 | Add-Content $TargetFile }
  • 我收到此错误:Get-Content : 特定路径处的对象不存在,或已被 -Include 或 -Exclude 参数过滤。
  • 去掉不需要的Get-ChildItem -Path $src -Recurse -File | Copy-Item -Destination $dst Get-Content $_.FullName | Select -Skip 1 | Add-Content $TargetFile
  • 感谢您的帮助!我按照指示做了,现在我在 powershell 中收到此错误: Get-Content : An object at the specified path C:\Users\E\Desktop\Merge\Input\Lapus\Files.csv 不存在,或者已经存在由 -Include 或 -Exclude 参数过滤。在 C:\Users\E\Desktop\test6.ps1:12 char:5 + 获取内容 $_ |选择 - 跳过 1 |添加内容 $TargetFile + ~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (System.String[]:String[]) [Get-Content], Exception + FullyQualifiedErrorId : ItemNotFound, Microsoft。 PowerShell.Commands.GetContentCommand –
  • 如果你只是在我的第二个代码块之前定义 $src$dst 它应该做你想做的事。
猜你喜欢
  • 1970-01-01
  • 2015-07-14
  • 2011-10-21
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
相关资源
最近更新 更多