2016-07-19 18 views
-1

Ich möchte zwei CSV-Dateien zusammenführen, die denselben Header in einer CSV-Datei enthalten. Ich habe zwei solche Dateien wie unten dh DevData.csv und ProdData.csv mit gleichen cfname und verschiedenen ID sZwei CSV-Dateien zusammenführen

 ID     cfname 
    -------------------- ----------------------------------- 
        10201 Risk ID 
        10202 Issue ID 
        10203 Dependency ID 
        10204 Server ID 
        10205 Parent Application ID 
        10206 Application Service ID 
        10207 Application Supportability 
        10208 Application Compatibility 
        10300 Application Status 
        10301 Contact ID Type 2 
        10302 Contact ID Type 3 
        10303 Contact ID Type 4 
        10304 Business Service Manager 
        10308 Server Location Name: 
        10309 Rack Position: 
        10310 Rack Number: 
        10311 Data Centre 
        10312 Server Group 
(14 rows affected)

ich neue CSV in folgendem Format erstellt werden soll gezeigt:

DevID    ProdID cfname 
-------------------- ------ ----------------------------------- 
       10201 201 Risk ID 
       10202 202 Issue ID 
       10203 203 Dependency ID 
       10204 204 Server ID 
       10205 205 Parent Application ID 
       10206 206 Application Service ID 
       10207 207 Application Supportability 
       10208 208 Application Compatibility 
       10300 209 Application Status 
       10301 210 Contact ID Type 2 
       10302 211 Contact ID Type 3 
       10303 212 Contact ID Type 4 
       10304 213 Business Service Manager 
       10308 214 Server Location Name:

Es folgt meine aktuellen Code , aber es exportiert Daten der ersten Datei und darunter die Daten der nächsten Datei.

function Merge-CSVFiles { 
    [cmdletbinding()] 
    param(
     [string[]]$CSVFiles 
    ) 

    $Output = @(); 
    foreach ($CSV in $CSVFiles) { 
     if (Test-Path $CSV) { 
      $FileName = [System.IO.Path]::GetFileName($CSV) 
      $temp = Import-CSV -Path $CSV | 
        select ID, cfname, ID, cfname, @{Expression={$FileName}} 
      $Output += $temp 
     } else { 
      Write-Warning "$CSV : No such file found" 
     } 
    } 
    $Output | Export-Csv -Path $OutputFile -NoTypeInformation 
    Write-Output "$OutputFile successfully created" 
} 

Merge-CSVFiles -CSVFiles "C:\Users\ECSAdmin\Desktop\Proddata.csv", "C:\Users\ECSAdmin\Desktop\Devdata.csv" -OutputFile "C:\Users\ECSAdmin\Desktop\Mergedata.csv" 
+1

"* zwei csv-Dateien, die den gleichen Header haben *" - aber 'ID, cfname' und' DevID, ProdID, cfname' sind nicht das Gleiche? – TessellatingHeckler

+0

DevID und ProdID werden in der Ausgabe CSV-Datei kommen. Ich habe die gleiche Abfrage auf Entwicklung (erstellt Devdata.csv) und Produktion (erstellt Proddata.csv) db, die gleiche Ausgabe mit unterschiedlichen ID.So möchte ich diese beiden Dateien zusammenführen mit ProdID, DevID und cfname als Kopfzeilen in der endgültigen Ausgabe-CSV-Datei. – Abhaya

+0

Sie müssen Header hinzufügen. 'import-csv -path ".csv" -Header DevID, ProdID, Cfname' und Zusammenführen von zwei csv ' $ merged = $ csv1 + $ csv2 fusionierte $ | Select -Property * -Unique – DisplayName

Antwort

0

Sie eine verschachtelte foreach Schleife über die zwei Sätze tun könnte, aber zwei, die Ausführungszeit wächst exponentiell in Bezug auf die Eingangsgröße vermeiden, eine bessere Strategie wäre einen Satz in eine Hash-Tabelle zu laden (die Verwendung von Allgemeingut cfname als Schlüssel) und dann die Schleife über die andere und die beiden verketten:

$DevData = @' 
ID,cfname 
10201,Risk ID 
10202,Issue ID 
10203,Dependency ID 
10204,Server ID 
10205,Parent Application ID 
10206,Application Service ID 
10207,Application Supportability 
10208,Application Compatibility 
10300,Application Status 
10301,Contact ID Type 2 
10302,Contact ID Type 3 
10303,Contact ID Type 4 
10304,Business Service Manager 
10308,Server Location Name: 
10309,Rack Position: 
10310,Rack Number: 
10311,Data Centre 
10312,Server Group 
'@ |ConvertFrom-Csv 

$ProdData = @' 
ID,cfname 
201,Risk ID 
202,Issue ID 
203,Dependency ID 
204,Server ID 
205,Parent Application ID 
206,Application Service ID 
207,Application Supportability 
208,Application Compatibility 
209,Application Status 
210,Contact ID Type 2 
211,Contact ID Type 3 
212,Contact ID Type 4 
213,Business Service Manager 
214,Server Location Name: 
'@ |ConvertFrom-Csv 

# throw one set into a hashtable 
# we can use this as a lookup table for the other set 
$ProdTable = @{} 
foreach($line in $ProdData){ 
    $ProdTable[$line.cfname] = $line.ID 
} 

# Output the DevData with the appropriate ProdData value 
$DevData |Select-Object @{Label='DevID';Expression={$_.ID}},@{Label='ProdID';Expression={$ProdTable[$_.cfname]}},cfname |Export-Csv .\new.csv -NoTypeInformation 
+0

Danke @Mathias Das funktioniert einwandfrei, wenn ich kopiere die CSV-Daten in die Variablen wie Sie erwähnt haben, aber nicht, wenn ich Import-CSV durchführen. Ich kann nicht kopieren die Daten die ganze Zeit kopieren, gibt es eine Möglichkeit, das gleiche zu erreichen, mit Import-CSV? – Abhaya

+0

@Supriya Wenn die CSV-Dateien den gleichen Inhalt wie die Zeichenfolgen in meinem Beispiel haben, ist die Ausgabe von 'Import-Csv' die gleiche wie die von 'ConvertFrom-Csv' über –

0

können Sie diese einfache Pipeline von Befehlen versuchen:

Out-file -FilePath '.\csv3.csv' -InputObject "ProdID,ID,cfname"; ForEach($CFName In $Csv1) { $Csv2.Where({$_.cfname -eq $CFName.cfname}) | %{ "$($_.ProdID),$($CFName.ID),$($_.cfName)" } | Out-File .\csv3.csv -Append} 

Wo ich annahm, dass Csv1.csv die erste Datei mit Spalten ID und Cfname ist und zweite Datei Csv2.csv Spalte ProdID und Cfname hat. Dies wird dritte Datei csv3.csv mit fusionierte Inhalt

0

erzeugen Da Sie Daten von SQL Server mit sqlcmd exportieren, können Sie die Parameter -W und -s"," hinzufügen müssen Ihren Befehl erstellen aktuelle CSV-Ausgabe haben:

sqlcmd -S server -d db -E -Q "query" -W -s"," -o output.csv 

Sobald Sie aktuelle CSV-Dateien haben, können Sie sie wie folgt verarbeiten:

# create a hashtable from the second CSV, so you can look up IDs by the 
# values in the "cfname" column 
$proddata = @{} 
Import-Csv 'C:\path\to\ProdData.csv' | ForEach-Object { 
    $proddata[$_.cfname] = $_.ID 
} 

Import-Csv 'C:\path\to\DevData.csv' | 
    Select-Object @{n='DevID';e={$_.ID}}, 
       @{n='ProdID';e={$proddata[$_.cfname}}, cfname | 
    Export-Csv 'C:\path\to\merged.csv' 

Dies übernimmt Ihre ProdData.csv nur cfname Werte enthält, die auch angezeigt werden in DevData.csv, und dass Ihre cfname Werte mindestens in ProdData.csv einzigartig sind. Eine bidirektionale Zusammenführung ist komplizierter, da Sie die Whick-Schlüssel in $proddata in DevData.csv nicht überprüfen und sie entsprechend anhängen müssen. Wenn Ihre cfname Werte nicht eindeutig sind, können Sie die Datensätze nicht ausrichten.

+0

Es gibt den folgenden Fehler in der Ausgabe aus. csv-Datei 'Sqlcmd: '"': Unerwartetes Argument. Eingeben '-?' um Hilfe. – Abhaya

+0

Das sieht wie ein typografisches Zitat aus. Benutze sie nicht im Code. –

+0

Es hat funktioniert. Vielen Dank :) – Abhaya