franz-josef-ii
Goto Top

Powershell - Dateien vergleichen und ergänzen

Guten Tag

Ich bin wieder einmal bei meiner CSV dran und hänge face-sad trotz Google und Co

Ausgangslage ist eine csv mit Namen, Kennung und Einsatzort face-wink :

Vorname;Nachname;Kennung;Ort
Sean;Connery;001;Berlin
Roger;Moore;002;Wien
George;Lazenby;003;Wien
Timothy;Dalton;004; London
Pierce;Brosnan;005;London
Daniel;Craig;006;Berlin
James;Bond;007;weltweit

Mit der kann ich ganz "normal" arbeiten. Jetzt kommt das jährliche Update, ein paar sind weg, ein paar haben den Ort gewechselt und es gibt ein paar neue. Ich bekomme jedoch "nur" die aktuelle Liste in dieser Form:

Vorname;Nachname;Ort
Sean;Connery;weltweit
Roger;Moore;weltweit
George;Lazenby;Berlin
Daniel;Craig;Hintertupfing
James;Bond;Wien
Max;Mustermann;Hintertupfing
Susi;Sorglos;München
Karli;Katastrophsky;Bonn
Jim;Bond;irgendwo

Somit fehlt eine Spalte und eine kann sich verändert haben.

Ich möchte jetzt eine dritte Datei auf Basis der zweiten, wobei diese die erste kontrolliert, gibt es den schon? Wenn ja, dann gib ihm die bestehende Nummer. Eine vierte mit allen die es nicht mehr gibt und eine fünfte mit den Neuzugängen.

Ich schaffe es zwar mit "compare" (auch über mehrere Spalten hinweg) zu vergleichen, bekomme aber das "gib ihm die Nummer" nicht hin. (Die vierte und fünfte, machma die Reihenfolge face-wink )

Bitte um ein Stichwort.

Content-Key: 351271

Url: https://administrator.de/contentid/351271

Ausgedruckt am: 19.03.2024 um 02:03 Uhr

Mitglied: 134464
134464 10.10.2017 um 11:32:11 Uhr
Goto Top
Stichwort where-object und group-object
Mitglied: Franz-Josef-II
Franz-Josef-II 10.10.2017 aktualisiert um 11:56:50 Uhr
Goto Top
where-object

Mit dem kann ich doch nur in den Ergebnissen nach kleiner, größer etc filtern?
https://technet.microsoft.com/de-at/library/ee177028.aspx


group-object

Hier wird doch nur die Reihenfolge nach irgendwas umgestellt?
https://technet.microsoft.com/de-at/library/ee176864.aspx


Irgendwie reden wir aneinander vorbei.
Die dritte Datei sollte so auschauen:
Vorname;Nachname;Ort;Kennung
Sean;Connery;weltweit;001
Roger;Moore;weltweit;002
George;Lazenby;Berlin;003
Daniel;Craig;Hintertupfing;005
James;Bond;Wien;007
Max;Mustermann;Hintertupfing;
Susi;Sorglos;München;
Karli;Katastrophsky;Bonn;
Jim;Bond;irgendwo;
Mitglied: 134464
134464 10.10.2017 aktualisiert um 12:04:07 Uhr
Goto Top
Zitat von @Franz-Josef-II:

where-object

Mit dem kann ich doch nur in den Ergebnissen nach kleiner, größer etc filtern?
https://technet.microsoft.com/de-at/library/ee177028.aspx

Falsch! Du kannst damit den passenden Eintrag in der anderen Datei suchen und damit auch zuordnen.
group-object

Hier wird doch nur die Reihenfolge nach irgendwas umgestellt?
Quatsch mit Soße! Du packst beide Dateien in ein Array und gruppierst dann nach Namen mit group object und gibst von der Gruppe die aus mit der Kennung!
Also erst mal selbst ausprobieren bevor du hier leichtfertig solche Thesen aufstellst...
Mitglied: colinardo
colinardo 10.10.2017 aktualisiert um 14:02:43 Uhr
Goto Top
Servus,
der Beschreibung von @kokosnuss kann ich nur zustimmen, und du wolltest ja eigentlich nur ein "Stichwort" face-wink. Naja, hier trotzdem mal ein Beispiel (Beispieldaten nur zur Demo ins Skript integriert, kann natürlich durch Import-CSV ersetzt werden)
$csv1 = @"  
Vorname;Nachname;Kennung;Ort
Sean;Connery;001;Berlin
Roger;Moore;002;Wien
George;Lazenby;003;Wien
Timothy;Dalton;004; London
Pierce;Brosnan;005;London
Daniel;Craig;006;Berlin
James;Bond;007;weltweit
"@ | ConvertFrom-CSV -Delimiter ";"  
$csv2 = @"  
Vorname;Nachname;Ort
Sean;Connery;weltweit
Roger;Moore;weltweit
George;Lazenby;Berlin
Daniel;Craig;Hintertupfing
James;Bond;Wien
Max;Mustermann;Hintertupfing
Susi;Sorglos;München
Karli;Katastrophsky;Bonn
Jim;Bond;irgendwo
"@ | ConvertFrom-CSV -Delimiter ";"  

$all = @()
$all += $csv1
$all += $csv2

$matching = $all | group Vorname,Nachname | %{$group = $_.group;$_.Group | select Vorname,Nachname,Kennung,@{n='Ort';e={@{$true=$group[1].Ort;$false=$_.Ort}[($group.Count -gt 1)]}}}  
$new = compare $csv1 $csv2 -Property Vorname,Nachname -PassThru | ?{$_.Sideindicator -eq '=>'}  
$nonexisting = compare $csv1 $csv2 -Property Vorname,Nachname -PassThru | ?{$_.Sideindicator -eq '<='}  

Grüße Uwe
Mitglied: Franz-Josef-II
Franz-Josef-II 10.10.2017 um 15:03:27 Uhr
Goto Top
Danke Uwe (auf Dich habe ich gehofft face-wink )

Aber das mit dem Stichwort paßt schon, ich will ja verstehen was ich da mache. Ich habe mich mit dem compare abgemüht und "nix z'sambracht", das where und group habe ich nur im Zusammenhang mit "wo ist des" und "sortier mia des" gesehen.

Dann werde ich mich da halt durchackern.

Danke
Mitglied: Franz-Josef-II
Franz-Josef-II 13.10.2017 um 07:45:35 Uhr
Goto Top
Guten Morgähhhhn

Ich sage nochmals recht herzlich "Danke schön", habe jedoch (noch zumindest) eine Frage:

Was macht der Teil des Script eigentlich genau? Den konnte ich (noch) nicht "zerlegen":

...... @{n='Ort';e={@{$true=$group[1].Ort;$false=$_.Ort}[($group.Count -gt 1)]}}  
Mitglied: colinardo
colinardo 13.10.2017 aktualisiert um 07:54:34 Uhr
Goto Top
Moin.
Das äußere ist eine sogenannte calculated property mit der man im Select Befehl schnell eine Spalte mit neuem Namen hinzufügen kann.
@{n="NamederneuenSpalte";e={Expression}}  

Innerhalb dieser Expression nutze ich eine Alternative für ein IF Konstrukt. Und zwar ist das eine Hashtable welche je nach Ergebnis (true oder false) den entsprechenden Wert zurückgibt
@{$true=$group[1].Ort;$false=$_.Ort}[($group.Count -gt 1)]
Wenn $group.count größer als 1 ist dann gebe den $true Teil der Hashtable zurück ansonsten den $false Teil.
Mitglied: Franz-Josef-II
Franz-Josef-II 13.10.2017 aktualisiert um 09:28:50 Uhr
Goto Top
Ok,

Zusammenfassung:

Zeile 24 erzeugt eine Variable mit Feldern
Zeile 25 schmeißt die erste und 26 die zweite csv-Datei hinein.

Zeile 28 das verstehe ich jetzt nicht auf Anhieb, da muß ich etwas länger darüber nachdenken und probieren face-wink trotzdem Danke

Zeile 29 und 30 vergleichen die beiden csv-Dateien und schmeißen die Unterschiede raus, einmal die, die nur in der ersten stehen und nicht in der zweiten und einmal umgekehrt.


Nachsatz:
Mit den "kurzen" Angaben der James Bond Darsteller funktioniert es, wie gewünscht. Ich habe mit nach den Zeilen 28 bis 30 je eine Datei auswerfen lasen, das paßt.. Mit den "echten" Dateien, jeweils so ca 1.100 Einträge geht es nicht. Hier wird z.B. bei der Zeile 28 eine Datei mit ca 2.200 Einträgen ( = 1 + 2) erstellt. Tja, schauma ob ma de Uasoch (=Völla) findn face-wink

Nachsatz 2:
Beim "Matching" hatte ich einen Fehler drinnen, sind zwar noch immer um einige zuviel drinnen, aber der Großteil ist weg.
Mitglied: colinardo
colinardo 13.10.2017 aktualisiert um 09:30:28 Uhr
Goto Top
Zitat von @Franz-Josef-II:
Zeile 24 erzeugt eine Variable mit Feldern
Nein, ein leeres Array.
Zeile 25 schmeißt die erste und 26 die zweite csv-Datei hinein.
Ja.
Zeile 28 das verstehe ich jetzt nicht auf Anhieb, da muß ich etwas länger darüber nachdenken und probieren face-wink trotzdem Danke
Im Endeffekt werden die Einträge die nun doppelt vorkommen (Vorname und Nachname) jeweils in eine Gruppe gepackt. Aus dieser Gruppe werden einerseits die Daten wie Vorname und Name entnommen und wenn es in der Gruppe mindestens 2 Einträge gibt wird von diesem zweiten der aktuellere Ort übernommen.
Du verstehst es besser wenn du dir die einzelnen Bestandteile einfach mal in der Konsole zerlegst und dir alles was hinter group kommt erst mal weglässt, dann lässt du dir die dort herausgekommenen Eigenschaften auflisten, dann verstehst du es besser.

Zeile 29 und 30 vergleichen die beiden csv-Dateien und schmeißen die Unterschiede raus, einmal die, die nur in der ersten stehen und nicht in der zweiten und einmal umgekehrt.
Korrekt.

Nachsatz:
Mit den "kurzen" Angaben der James Bond Darsteller funktioniert es, wie gewünscht. Ich habe mit nach den Zeilen 28 bis 30 je eine Datei auswerfen lasen, das paßt.. Mit den "echten" Dateien, jeweils so ca 1.100 Einträge geht es nicht. Hier wird z.B. bei der Zeile 28 eine Datei mit ca 2.200 Einträgen ( = 1 + 2) erstellt. Tja, schauma ob ma de Uasoch (=Völla) findn face-wink
Tja ohne deine echten Daten kann ich hier leider nichts mutmaßen. Da wirst du etwas falsch angepasst haben.
Gegen Aufwandsentschädigung schaue ich mir die gerne an => PN.
Mitglied: Franz-Josef-II
Franz-Josef-II 17.10.2017 aktualisiert um 09:29:19 Uhr
Goto Top
Guten Morgen

Ok, ein kleines bißchen klarer wirds face-wink bzw ist es geworden.

Ich durchblicke folgendes nicht:
... $group = $_.group;$_.Group ....
... $true=$group[1].... 

Was bewirken die [Zahl]?


Edith:
Es ist zwar ein "bemisches Deitsch" aber ich denke, ich habe es gefunden:
https://technet.microsoft.com/de-de/library/hh551144.aspx
Gibts da vielleicht etwas .... naja, sagen wir "anfängertauglicheres"? face-wink

Edith2:
Tja, wirklich "bemisch"face-wink

Ok, das [Zahl] gibt an , das wievielte Objekt .... Zählweise beginnt bei 0.
Beim ... $true=$group[1].... wird geprüft, ob es in dieser Gruppe, ein zweites gibt und falls ja, wird dieses verwendet, falls nein,zieht das: .Ort;$false=$_.Ort}
Mitglied: colinardo
colinardo 17.10.2017 aktualisiert um 15:28:55 Uhr
Goto Top
Das ist ein simpler Arrayindex der das jeweilige Element eines Arrays zurückgibt.
Statt der Hashtable Methode kannst du jederzeit alternativ zur If-Abfrage greifen, die erledigt das ebenfalls wie gewünscht wenn du damit besser klar kommst.