muhmuh
Goto Top

PowerShell CSV-Datei in bestimmtes Format umwandeln

Hallo Zusammen,

Der Inhalt einer CSV-Datei soll in eine Matrix überführt werden.

Leider komme ich mit PowerShell hier nicht weiter. Mit Excel ist es machbar, aber ich möchte es doch lieber komplett in PowerShell bearbeiten.

So sieht meine CSV-Datei aus:
"USER1","APP1 APP4 APP5"
"USER2","APP1 APP2"
"USER3","APP6 APP7"
"USER4","APP3 APP4"
"USER5","APP1 APP9"
"USER6","APP9"

Nun würde ich diese gerne folgendermaßen umwandeln:
LOGIN;APP1;APP2;APP3;APP4;APP5;APP6;APP7;APP8;APP9
"USER1";X;;;X;X;;;;;;
"USER2";X;X;;;;;;;;;
"USER3";;;;;;X;X;;;;
"USER4";;;X;X;;;;;
"USER5";X;;;;;;;;X
"USER6";;;;;;;;;X

matrix
Über jede Anregung, wie dies in PowerShell möglich wäre, würde ich mich freuen.

Gruß
Willi

Content-Key: 374375

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

Printed on: April 26, 2024 at 19:04 o'clock

Member: tfi2013
tfi2013 May 18, 2018 updated at 22:26:54 (UTC)
Goto Top
Nabend.

Versuch es mal hiermit:

Was Du anpassen musst, sind die Pfade für die CSV-Datein.
z.B.: In der ersten Zeile: "D:\test.csv" & in der letzten Zeile: "D:\new.csv"


$CSVToConvert = Get-Content "D:\test.csv" | ConvertFrom-Csv -Header Login,App  

$NewCsvLine = "" | Select Login, App1, App2, App3, App4, App5, App6, App7, App8, App9  

[Array] $NewCsv = @()


For($i=0; $i -lt $CSVToConvert.Login.Count; $i++){
    $SplittedApp = $CSVToConvert.App[$i].Split(" ")  

    For($j=0; $j -lt $SplittedApp.Count; $j++){
        Switch($SplittedApp[$j]){
            "APP1" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App1 = "X"; Break}  
            "APP2" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App2 = "X"; Break}  
            "APP3" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App3 = "X"; Break}  
            "APP4" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App4 = "X"; Break}  
            "APP5" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App5 = "X"; Break}  
            "APP6" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App6 = "X"; Break}  
            "APP7" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App7 = "X"; Break}  
            "APP8" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App8 = "X"; Break}  
            "APP9" {$NewCsvLine.Login = $CSVToConvert.Login[$i]; $NewCsvLine.App9 = "X"; Break}  
        }
    }

    $NewCsv = [Array]$NewCsv + $NewCsvLine
    $NewCsvLine = "" | Select Login, App1, App2, App3, App4, App5, App6, App7, App8, App9  
}


$NewCsv | Select Login, App1, App2, App3, App4, App5, App6, App7, App8, App9 | Export-Csv -Path "D:\new.csv" -Delimiter ";" -NoTypeInformation  

Gruß
tfi2013
Member: colinardo
Solution colinardo May 19, 2018 updated at 14:13:16 (UTC)
Goto Top
Servus Willi,
eleganter und ohne feste Zuweisung von Appnamen wäre das hier:
# Eingabedatei
$fileIN = 'D:\apps.csv'  
# Ausgabedatei
$fileOUT = 'D:\apps_new.csv'  
# =========================
# Import mit neuem Header
$csv = Import-CSV $fileIN -Delimiter ',' -Header 'Login','Raw'  
# App Member hinzufügen
$csv | %{$_.Raw.Split(' ').Trim()} | select -Unique | %{$csv | Add-Member -MemberType NoteProperty -Name $_ -Value '' -Force}  
# zugehörige Apps zuweisen
foreach($entry in $csv){
    $entry.Raw.Split(' ').Trim() | %{$entry.$_ = 'X'}  
}
# output
$csv | select -Exclude Raw | export-csv $fileOUT -Delimiter ';' -NoType -Encoding UTF8  
Grüße Uwe
Member: MuHMuH
MuHMuH May 19, 2018 at 16:59:14 (UTC)
Goto Top
Hallo Uwe,

vielen Dank für Deine tolle und "knackige" Lösung. Darauf wäre ich selbst nie gekommen.

Das Script läuft super und ist auch noch wahnsinnig schnell.
Bei meiner Originalliste mit ca. 5000 Zeilen dauerte es nicht mal 5 Sekunden.

Nun muss ich nur noch das Script "richtig" verstehen face-wink.
Die SPLIT-Funktion kannte ich bisher noch gar nicht.

Einen schönen Abend/Feiertag wünscht Dir
Willi
Member: MuHMuH
MuHMuH May 19, 2018 updated at 17:06:01 (UTC)
Goto Top
Hallo tfi2013,

vielen Dank für Deinen interessanten Lösungsansatz.

Da die Lösung von Uwe für mein Projekt super funktioniert, werde ich aber dessen Lösung verwenden.

Schöne Pfingstfeiertage
Willi
Member: MuHMuH
MuHMuH May 19, 2018 at 19:03:51 (UTC)
Goto Top
Hallo Uwe,

inzwischen habe ich mir das Script genauer angesehen und soweit habe ich es auch verstanden face-wink

Nur beim nachfogenden Teil habe ich eine Frage:
Kannst Du mir bitte die genaue Funktion des %-Zeichen erläutern?

$csv | %{$_.Raw.Split(' ').Trim()} | select -Unique | %{$csv | Add-Member -MemberType NoteProperty -Name $_ -Value '' -Force}

Vielen Dank
Willi
Member: colinardo
Solution colinardo May 19, 2018 updated at 19:13:48 (UTC)
Goto Top
Hi Willi,
das ist schnell erklärt, das %{} ist eine Abkürzung für eine Foreach Schleife, bzw. die Abkürzung für das cmdlet foreach-object, genauso wie das ?{} eine Abkürzung für ein where-object ist.

Schönen Abend
Uwe
Member: MuHMuH
MuHMuH May 19, 2018 at 20:10:52 (UTC)
Goto Top
Hallo Uwe,

vielen Dank für die Erläuterung. Nun ist mir die Funktion klar.

Auch Dir einen schönen Abend
Willi
Member: tfi2013
tfi2013 May 19, 2018 at 20:52:50 (UTC)
Goto Top
Hallo Willi,

kein Problem.

Das von mir war auch nur ein Schnell-Ansatz. face-smile

Dir auch schöne Pfingstfeiertage.

Gruß
Thomas