white printing paper with numbers

Grosse CSV Dateien in mehrere kleine aufteilen

Manchmal steht man vor dem Problem, ein riesiges Excel oder eine CS geliefert zu bekommen, aber man möchte diese in kleine Häppchen aufteilen. Beispielsweise um mehrere Exchange Hybridmigrationsbatches zu erstellen.

In diesem Beispiel arbeite ich mit diesen exemplarischen Daten:

Firstname;LastName;Country
Max;Mustermann;Germany
Maria;Musterfrau;Germany
Igor;Smirnow;Russia
John;Dow;USA
Felix;Frisch;Germany

Wie man sieht, spielt es keine Rolle ob die Daten sortiert sind. Um zu starten, muss man der PowerShell nur sagen, wie sie diese CSV einlesen soll:

$GroupField = "Country"
$Delimiter = ";"
$csv = "C:\tmp\MyBigCSVWithTonsOfData.csv"
$outfolder = "C:\tmp\CSV-Files\"

Was machen diese Parameter? Ganz einfach:

  • $GroupField steuert, nach welchem Feldwert die Daten sortiert werden sollen
  • $Delimiter legt das Trennzeichen fest
  • $csv ist der volle Pfad zur CSV die in kleinere aufgeteilt werden soll
  • $outfolder ist der Pfad zum Ordner, wo die Ergebnisdateien abgelegt werden sollen

Nach der Vorbereitung muss nun die CSV eingelesen werden und die Daten für die Splittung sortiert werden:

$all = Import-Csv $csv -Delimiter $Delimiter
$groupedCollection = $all | Group-Object $GroupField

Ich nutze Group-Object was sich grob gesagt so wie die Excel-Filter-Funktion verhält. Mit diesem Kommando kann man strukturierte Daten gruppieren und das Ergebnis in mehrere Gruppen aufteilen. Bei 5 Einträgen in der CSV, einer Gruppierung nach Land ergibt das (bei 3x Germany, 1x USA und 1x Russia) 3 Gruppen:

  • eine Gruppe mit 3 Einträgen – mit Land „Germany“
  • eine Gruppe mit 1 Eintrag – mit Land „USA“
  • eine Gruppe mit 1 Eintrag – mit Land „Russia“
PSGroup

Sieht man sich den Rückgabewert genauer an, sieht man, dass die Variable $groupcollection ein Array ist:

$groupCollection.GetType()

Arbeiten mit Array ist einfach, kennt man aus vielen PowerShell Scripts. Man kann einfach mit foreach durch die Elemente zählen:

foreach($group in $groupedCollection)
{
   Write-Host ("Group '" + $group.Name + "' // " + $group.Count.ToString() + " Members")
   $group.Group | ConvertTo-Csv -NoTypeInformation -Delimiter "," | Out-File ($outfolder + $group.Name + ".csv")
}

Et voila, das Ergebnis sind 3 CSV Dateien – eine pro Land:

PSGroup2

Jetzt kann man die Arbeit mit den kleineren CSV Dateien fortsetzen. Ich habe in diesem Beispiel hart mit dem Trennzeichen „,“ gearbeitet. Natürlich funktioniert das auch mit anderen Trennzeichen.

Zum Abschluß das gesamte Script zum rauskopieren:

$GroupField = "Company"
$Delimiter = ";"
$csv = "S:\CSV-Files\MyBigCSVWithTonsOfData.csv"
$outfolder = "S:\CSV-Files\"

$all = Import-Csv $csv -Delimiter $Delimiter
$groupedCollection = $all | Group-Object $GroupField

foreach($group in $groupedCollection)
{
   Write-Host ("Group '" + $group.Name + "' // " + $group.Count.ToString() + " Members")
   $group.Group | ConvertTo-Csv -NoTypeInformation -Delimiter "," | Out-File ($outfolder + $group.Name + ".csv")
}

Published by Andreas

Gründer von M365 Evangelists Cloud-Architekt, Strategieberater, Consultant für Microsoft Technologien Graph API Enthusiast, PowerShell Enthusiast