joe2017
Goto Top

Powershell - durchsuche TXT Datei und füge mehrfach gleiche Werte in eine Zeile zusammenfassen

Ich habe folgende Datei und muss diese umstrukturieren. Hier komme ich nicht weiter.

Ich habe eine Datei a.txt mit folgendem Inhalt:
maier;3
maier;4
maier;9
müller;1
müller;2
müller5
müller8
müller6
usw.

die Namen kenne ich leider nicht. Diese sind unbekannte Variablen. Ich möchte das die Datei am Ende wie folgt aussieht.
maier;3;4;9
müller;1;2;5;8;6
usw.

Irgendwie finde ich hierzu nichts passendes und selbst komm ich leider auch nicht weiter.

Vielen Dank schon mal für die Mithilfe.

Content-Key: 360739

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

Printed on: April 23, 2024 at 23:04 o'clock

Member: colinardo
Solution colinardo Jan 11, 2018, updated at Jan 12, 2018 at 07:05:53 (UTC)
Goto Top
Da gibt's mehrere Varianten, hier mal schnell zwei mit der Zuhilfenahme von Group-Object das für solche Dinge prädestiniert ist.
$file = 'c:\a.txt'  
(Import-CSV $file -delimiter ";" -Header 'Name','Wert' -Encoding Default) | group Name | %{"$($_.Name);$($_.Group.Wert -join ';')"} | sc $file  
oder
$file = 'c:\a.txt'  
(gc $file) | group {$_.split(';')} | %{  
    $werte = ($_.Group | %{$cols = $_.split(';');if ($cols.Count -gt 1){$cols[1]}}) -join ';'  
    "$($_.Name);$werte"  
} | sc $file
Alternativ kannst du auch die Textdatei manuell mit einer For-Each-Schleife durchlaufen Namen und Wert splitten und in eine Hashtable schreiben bei der du die Werte immer anhängst.
$file = "C:\a.txt"  
$werte = [ordered]@{}
(gc $file) | %{
    $cols = $_.split(';')  
    $name = $cols
    if ($cols.Count -gt 1){
        [string[]]$werte.$name += $cols[1]
    }else{
        $werte.$name  = ""  
    }
}
$werte.GetEnumerator() | %{"$($_.Key);$($_.Value -join ';')"} | sc $file  

Das wäre die alte Methode, aber warum so wenn es Group-object gibt, was das für dich schon erledigt face-smile.

Nun darfst du dich bedienen face-wink.

Schönen Abend
Uwe
Member: joe2017
joe2017 Jan 12, 2018 at 08:13:56 (UTC)
Goto Top
Hi Uwe,

ich wüsste nicht was ich ohne dich machen würde. *lach*
Vielen Dank.

Die erste Variante hat bestens funktioniert
$file = 'c:\a.txt'  
(Import-CSV $file -delimiter ";" -Header 'Name','Wert' -Encoding Default) | group Name | %{"$($_.Name);$($_.Group.Wert -join ';')"} | sc $file  

Hier müsste ich doch theoretisch auch eine maximallänge für Werte pro Zeile festlegen können oder?
Bzw. sagen können das es immer Bsp. 10 Werte sind und den rest einfach mit "" getrennt durch ein ";" auffüllen.
Member: colinardo
colinardo Jan 12, 2018 updated at 08:27:28 (UTC)
Goto Top
Hier müsste ich doch theoretisch auch eine maximallänge für Werte pro Zeile festlegen können oder?
Bzw. sagen können das es immer Bsp. 10 Werte sind und den rest einfach mit "" getrennt durch ein ";" auffüllen.
Hmm. verstehe nicht ganz was du meinst. Meinst du so?
"Müller";"1;2;3;4"  
Also wie eine korrekte CSV normalerweise gefüllt sein sollte?

Habe mich nämlich schon gewundert das du zum Trennen beides mal sowohl den Namen von den Werten also auch die Werte das Semikolon haben wolltest ...
Member: joe2017
joe2017 Jan 12, 2018 updated at 08:35:32 (UTC)
Goto Top
Ich glaube das muss ich mit einem Array machen.

ich habe die Zeilen vorher sortiert und habe folgendes Ergebnis.
maier;3;4;9 
müller;1;2;5;8;6
 

ich möchte aber das die Zeilen mit ";" aufgefüllt werden bis es 10 Werte sind.
name;wert01;wert02;wert03;wert04;wert05;wert06;wert07;wert08;wert09;wert10
maier;3;4;9;;;;;;;
müller;1;2;5;8;6;;;;;;
 

Dazu müsste ich doch ein Array mit einem count oder .length verwenden. Oder geht das einfacher?
Der Sinn dahinter ist, dass ich diese Datei wieder einlese und weiter verarbeite.


$csv = import-csv -path $file -delimiter ";"  
$csv | %{
if ($_.'name' - match $var){  
$wert01 = $_.'wert01'  
$wert02 = $_.'wert02'  
$wert03 = $_.'wert03'  
$wert04 = $_.'wert04'  
$wert05 = $_.'wert05'  
$wert06 = $_.'wert06'  
$wert07 = $_.'wert07'  
$wert08 = $_.'wert08'  
$wert09 = $_.'wert09'  
$wert10 = $_.'wert10'  
}
}
Member: colinardo
colinardo Jan 12, 2018 updated at 08:44:21 (UTC)
Goto Top
Export
$file = 'A:\a.txt'  
(Import-CSV $file -delimiter ";" -Header 'Name','Wert') | group Name | %{  
    $obj = [pscustomobject]@{Name=$_.Name}
    $cnt = 1
    $_.Group.Wert | %{$obj | Add-Member -MemberType NoteProperty -Name $cnt -Value $_ -Force; $cnt++}
    $obj
} | export-csv $file -NoType -Delimiter ";" -Encoding UTF8  
Import
$file = 'A:\datei.csv'  
$csv = Import-CSV $file -delimiter ";"  
$csv
In der Schleife dann die Werte ansprechbar mit Nummern 1-X
$_.1, $_.2 usw.
Member: joe2017
joe2017 Jan 12, 2018 at 08:51:42 (UTC)
Goto Top
Ich denke das war ein Denkfehler! Ohhh Mann!
Wenn ich die Datei anschließend wieder einlese, muss ja nicht zwingend ein Wert für jede Variable $_.'wertxx' vorhanden sein.
Daher muss ich die Zeilen eigentlich auch nicht auffüllen!

Aber Super für deine Hilfe!!!