使用PowerShell将多个CSV文件合并为一个

joh*_*n50 21 csv powershell batch-file

您好我正在寻找powershell脚本,它将目录中的所有csv文件合并到一个文本文件(.txt)中.所有csv文件都有相同的标题,它总是存储在每个文件的第一行.所以我需要从第一个文件中获取头文件,但是在其余文件中应该跳过第一行.我能够找到完全符合我需要的批处理文件,但是我在一个目录中有超过4000个csv文件,并且完成这项工作需要45分钟以上.

@echo off
ECHO Set working directory
cd /d %~dp0
Deleting existing combined file
del summary.txt
setlocal ENABLEDELAYEDEXPANSION
set cnt=1
for %%i in (*.csv) do (
 if !cnt!==1 (
 for /f "delims=" %%j in ('type "%%i"') do echo %%j >> summary.txt
) else (
 for /f "skip=1 delims=" %%j in ('type "%%i"') do echo %%j >> summary.txt
 )
 set /a cnt+=1
 )
Run Code Online (Sandbox Code Playgroud)

任何建议如何创建powershell脚本比这批代码更有效?

谢谢.

约翰

kem*_*002 38

这会将所有文件追加到一起读取一个:

get-childItem "YOUR_DIRECTORY\*.txt" 
| foreach {[System.IO.File]::AppendAllText
 ("YOUR_DESTINATION_FILE", [System.IO.File]::ReadAllText($_.FullName))}

# Placed on seperate lines for readability
Run Code Online (Sandbox Code Playgroud)

如果需要,这个将在每个文件条目的末尾放置一个新行:

get-childItem "YOUR_DIRECTORY\*.txt" | foreach
{[System.IO.File]::AppendAllText("YOUR_DESTINATION_FILE", 
[System.IO.File]::ReadAllText($_.FullName) + [System.Environment]::NewLine)}
Run Code Online (Sandbox Code Playgroud)

跳过第一行:

$getFirstLine = $true

get-childItem "YOUR_DIRECTORY\*.txt" | foreach {
    $filePath = $_

    $lines =  $lines = Get-Content $filePath  
    $linesToWrite = switch($getFirstLine) {
           $true  {$lines}
           $false {$lines | Select -Skip 1}

    }

    $getFirstLine = $false
    Add-Content "YOUR_DESTINATION_FILE" $linesToWrite
    }
Run Code Online (Sandbox Code Playgroud)


小智 35

如果你正在使用单行程,你可以将每个csv传输到一个Import-Csv,然后立即将其传输到Export-Csv.这将保留初始标题行并排除其余文件标题行.它还将一次处理一个csv,而不是将所有csv加载到内存中,然后将它们转储到合并的csv中.

Get-ChildItem -Filter *.csv | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv .\merged\merged.csv -NoTypeInformation -Append
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案imho:简短,直白,有效. (3认同)

小智 8

试试这个,它对我有用

Get-Content *.csv| Add-Content output.csv
Run Code Online (Sandbox Code Playgroud)

  • 此方法不会跳过标题行。它将把每个文件的标题放入合并的 csv 中。 (4认同)

Bac*_*its 7

这在 PowerShell 中是相当微不足道的。

$CSVFolder = 'C:\Path\to\your\files';
$OutputFile = 'C:\Path\to\output\file.txt';

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

$CSV | Export-Csv -Path $OutputFile -NoTypeInformation -Force;
Run Code Online (Sandbox Code Playgroud)

这种方法的唯一缺点是它确实解析每个文件。它还会将所有文件加载到内存中,因此,如果我们谈论的是 4000 个文件,每个文件大小为 100 MB,那么您显然会遇到问题。

System.IO.File使用和可能会获得更好的性能System.IO.StreamWriter

  • @Zachafer 谢谢。我很清楚这个问题,但这是一个古老的答案。我已经用更好的模式替换了代码。 (2认同)