2016-06-10 8 views
0

Ich versuche, meine Ergebnisse aus einem Compare-Objekt in eine CSV zu exportieren, aber ich bekomme einen Fehler, wenn ich es exportieren. Es sieht gut aus, wenn ich es nur in Excel anrufe. Meine Vermutung ist, dass, wenn es eine Ausgabe von mehr als einem Wert gibt, der Fehler anstelle des Wertes platziert wird.System Objekt Fehler beim Exportieren von Ergebnissen in CSV

Hier sind meine CSVs past.csv

VKEY 
V-12345 
V-23456 
V-1111 

current.csv

VKEY 
V-12345 
V-6789 
V-23456 
V-256 

Meine neue csv

Past, Current 
V-6789,V-1111 
V-256 

sagen sollte, was ich bin immer jetzt ist

Past, Current 
System.Object[],@{vkey=V-1111} 

.

$Past = Import-CSV "past.csv" 
$Current = Import-CSV "Current.csv" 

$pastchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '=>'} | Select-Object VKEY 
$currentchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '<='} | Select-Object VKEY 

$obj = New-Object PSObject 
$obj | Add-Member NoteProperty Past $pastchange 
$obj | Add-Member NoteProperty Current $currentchange 
$obj | Export-Csv "ChangeResults.csv" -NoTypeInformation 

Antwort

1

Das System.Object[] in $obj.Past Spalte angezeigt ist einfach eine Reihe von benutzerdefinierten Objekte zu @{vkey=V-1111} in $obj.Past Spalte ähnlich. Proof:

PS D:\PShell> $obj 
$obj.Past.Gettype() | Format-Table 
$obj.Current.Gettype() 
"---" 
$obj.Past | ForEach-Object { $_.Gettype() } 

Past          Current         
----          -------         
{@{vkey=V-6789}, @{vkey=V-256}}   @{vkey=V-1111}       

IsPublic IsSerial Name          BaseType     
-------- -------- ----          --------     
True  True  Object[]         System.Array    

IsPublic IsSerial Name          BaseType     
-------- -------- ----          --------     
True  False PSCustomObject       System.Object    
--- 
True  False PSCustomObject       System.Object    
True  False PSCustomObject       System.Object    

Meine Lösung nutzt ArrayList Class (.NET Framework):

$csvOutFile = "d:\test\ChangeResults.csv" # change to fit your circumstances 
$PastInFile = "d:\test\past.csv" 
$CurrInFile = "d:\test\curr.csv" 

$Past = Import-CSV $PastInFile 
$Curr = Import-CSV $CurrInFile 

# compare CSV files and convert results to arrays 
[email protected](,          <# always return an array   #> 
      $(Compare-Object $Past $Curr -Property vkey | 
       Where-Object { $_.SideIndicator -eq '=>' }) | 
      ForEach-Object { $_ | Select-Object -ExpandProperty vkey } 
     ) 
[email protected](,          <# even if no SideIndicator matches #> 
      $(Compare-Object $Past $Curr -Property vkey | 
       Where-Object { $_.SideIndicator -eq '<=' }) | 
      ForEach-Object { $_ | Select-Object -ExpandProperty vkey } 
     ) 

[System.Collections.ArrayList]$csvout = New-Object System.Collections.ArrayList($null) 
$auxHash = @{}          # an auxiliary hash object 

$max = ($CurrCh.Count, $PastCh.Count | Measure-Object -Maximum).Maximum 
for ($i=0; $i -lt $max; $i++) { 
    Try { $auxHash.Past = $PastCh.GetValue($i) } Catch { $auxHash.Past = '' } 
    Try { $auxHash.Curr = $CurrCh.GetValue($i) } Catch { $auxHash.Curr = '' } 
    $csvout.Add((New-Object PSObject -Property $auxHash)) > $null 
} 
$csvout | Format-Table -AutoSize  # show content: 'variable $csvout' 

$csvout | Export-Csv $csvOutFile -NoTypeInformation 
Get-Content $csvOutFile    # show content: "output file $csvOutFile" 

Ausgang:

PS D:\PShell> D:\PShell\SO\37753277.ps1 

Past Curr 
---- ---- 
V-6789 V-1111 
V-256   


"Past","Curr" 
"V-6789","V-1111" 
"V-256","" 

PS D:\PShell> 

Hier ist eine Alternative für Try ... Catch Blöcke:

<# another approach instead of `Try..Catch`: 
    if ($i -lt $PastCh.Count) { $auxHash.Past = $PastCh.GetValue($i) 
         } else { $auxHash.Past = '' } 
    if ($i -lt $CurrCh.Count) { $auxHash.Curr = $CurrCh.GetValue($i) 
         } else { $auxHash.Curr = '' } 
    #> 
Verwandte Themen