1
+ <#
2
+ . SYNOPSIS
3
+ This script concatenates multiple CSV files into a single CSV file.
4
+
5
+ . DESCRIPTION
6
+ The Invoke-ConcatenateCSV.ps1 script concatenates multiple CSV files from a specified directory into a single CSV file, adding the source filename as the first column.
7
+ A oneliner exists:
8
+ Get-ChildItem -Filter *.csv | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv .\merged.csv -NoTypeInformation -Append
9
+ But we don't have the source file name in the output file and we can handle different properties in the CSV files.
10
+
11
+ . PARAMETER InputDirectory
12
+ Specifies the directory containing the CSV files to be concatenated.
13
+
14
+ . PARAMETER OutputFile
15
+ Specifies the path and name of the output CSV file that will contain the concatenated data.
16
+
17
+ . EXAMPLE
18
+ PS C:\> .\Invoke-ConcatenateCSV.ps1 -InputDirectory "C:\CSVFiles" -OutputFile "C:\Output\Combined.csv"
19
+
20
+ . NOTES
21
+ Author: Bastien Perez
22
+ Date: 2024/11/22
23
+ Version: 1.2
24
+ #>
25
+
26
+ function Invoke-ConcatenateCSV {
27
+ [CmdletBinding ()]
28
+ param (
29
+ [Parameter (Mandatory = $false )]
30
+ [string ]$InputDirectory = ' .' ,
31
+
32
+ [Parameter (Mandatory = $false )]
33
+ [string ]$OutputFile = ' Concatenated.csv' ,
34
+
35
+ [Parameter (Mandatory = $false )]
36
+ [string ]$Delimiter = ' ;' ,
37
+
38
+ [Parameter (Mandatory = $false )]
39
+ [switch ]$AddSourceFile
40
+ )
41
+
42
+ # Create empty array to store all data
43
+ [System.Collections.Generic.List [Object ]]$allData = @ ()
44
+ # Get all CSV files in the specified directory
45
+ $files = Get-ChildItem - Path $InputDirectory - Filter ' *.csv'
46
+
47
+ if ($files.Count -eq 0 ) {
48
+ Write-Warning " No CSV files found in directory: $InputDirectory "
49
+ return
50
+ }
51
+
52
+ foreach ($file in $files ) {
53
+ Write-Verbose " Processing file: $ ( $file.Name ) "
54
+
55
+ try {
56
+ # Import CSV content
57
+ Write-Verbose " Importing CSV content from: $ ( $file.FullName ) "
58
+ $csvContent = Import-Csv - Path $file.FullName - Delimiter $Delimiter
59
+
60
+ # Add source filename to each row
61
+ foreach ($row in $csvContent ) {
62
+ if ($AddSourceFile ) {
63
+ Write-Verbose " Adding source file = $ ( $file.Name ) to the row"
64
+ $row.PSObject.Properties.Add (' SourceFile' , $file.Name )
65
+ }
66
+
67
+ $newRow = @ {}
68
+ # Add all other properties from the original row
69
+ foreach ($property in $row.PSObject.Properties ) {
70
+ Write-Verbose " Adding property: $ ( $property.Name ) = $ ( $property.Value ) "
71
+ $newRow [$property.Name ] = $property.Value
72
+ }
73
+
74
+ # Add the modified row to our collection
75
+ $allData.Add ([PSCustomObject ]$newRow )
76
+ }
77
+ }
78
+ catch {
79
+ Write-Warning " Error processing file $ ( $file.Name ) : $_ "
80
+ continue
81
+ }
82
+ }
83
+
84
+ if ($allData.Count -gt 0 ) {
85
+ try {
86
+ # Export all data to the output file
87
+ $allData | Export-Csv - Path $OutputFile - NoTypeInformation - Encoding UTF8
88
+ Write-Host " Successfully concatenated $ ( $files.Count ) files to: $OutputFile "
89
+ Write-Host " Total rows: $ ( $allData.Count ) "
90
+ }
91
+ catch {
92
+ Write-Error " Error writing output file: $_ "
93
+ }
94
+ }
95
+ else {
96
+ Write-Warning ' No data was collected from the CSV files'
97
+ }
98
+ }
0 commit comments