none
csv datei einlesen und nach inhalten in neue schreiben RRS feed

  • Frage

  • Hallo aus Hessen,

    ich habe schon ein wenig mit Powershell gearbeitet und stehe vor einem Problem, das ich zwar logisch erklären kann, aber powershell nicht genug kenne um das umzusetzen.

    Folgendes: Angenommen ich habe eine Liste in diesem Format:

    User;Wert
    A1;20
    A2;5
    A3;4
    A4;37
    A5;18
    A6;40
    A7;13
    A8;10
    A9;8
    A10;25

    Ziel ist es aus dieser Datei  Einzeldateien zu bilden, in denen jeweils User mit Wert kleiner gleich 40 sind. Im beispiel würde dann A1,A2,A3 und A8 in einer Datei stehen und A4 einzeln in einer Datei stehen. Und A5,A7 in einer Datei.

    Hat jemand eine Idee wie man sowas umsetzen kann? 

    Viiiiiieeelen Dank

    Jens

    Freitag, 15. April 2016 11:49

Antworten

  • Hallo,

    so habe mal zwischendurch ein wenig gebastelt, das Ganze kann man noch optimieren und es wird auch nicht beachtet wenn ein User alleine einen Wert > 40 hat, geht aus deinen Infos nicht heervor ob es sowas gibt ...

    Es funktioniert

    $Werte = Import-Csv .\xxx.csv
    $i = 0
    $j = 1
    $UserSumme = 0
    $ArrayBearbeitet = New-Object System.Collections.ArrayList
    Do {
    	if ((($UserSumme + $Werte[$i].Wert) -le 40) -and (-not ($ArrayBearbeitet.Contains($i)))) {
    		$UserSumme += $Werte[$i].Wert
    		$Null = $ArrayBearbeitet.Add($i)
    		$Werte[$i] | export-csv ".\zzFile-$j.csv" -append  -NoTypeInformation
    	}
    	$i++
    	if ($i -eq $Werte.count -and $ArrayBearbeitet.count -lt $Werte.count) {
    		$j++
    		$UserSumme = 0
    		$i = 0
    	}
    } until (($i -ge $Werte.count) -and ($ArrayBearbeitet.count -eq $Werte.count))
    

    Ergebnis:
    zzFile-1.csv
    "User","Wert"
    "A1","20"
    "A2","5"
    "A3","4"
    "A8","10"

    zzFile-2.csv
    "User","Wert"
    "A4","37"

    zzFile-3.csv
    "User","Wert"
    "A5","18"
    "A7","13"
    "A9","8"

    zzFile-4.csv
    "User","Wert"
    "A6","40"

    zzFile-5.csv
    "User","Wert"
    "A10","25"

    Beste Gruesse
    brima

    • Als Antwort markiert Jens0312 Freitag, 15. April 2016 16:32
    Freitag, 15. April 2016 14:24

Alle Antworten

  • Hi, schau mal, ob dir folgender Ansatz weiterhilft:
    $user = Import-Csv -Path "C:\Temp\user.csv" -Delimiter: ";"
    
    $gruppe1 = ($user | Where-Object {[int]$_.Wert -lt 40})
    $gruppe2 = ($user | Where-Object {[int]$_.Wert -ge 40})
    
    $gruppe1 | Out-File -FilePath "C:\temp\kleiner40.txt" 
    $gruppe2 | Out-File -FilePath "C:\temp\groesser40.txt"


    Christian Groebner MVP Forefront



    Freitag, 15. April 2016 12:15
  • Hallo,

    redest du jetzt von dem Wert für einen User <= 40, oder für kummulierte Werte von Usern <=40. Also es sollten immer soviele Users in eine Datei solange die Addition deren Werte <= 40 ist?

    Beste Gruesse
    brima

    Freitag, 15. April 2016 12:34
  • Hallo, 

    danke für die Antworten. Ja, es sollen immer so viel User in eine datei wie deren Wert <=40 ist.

    Viele Grüße

    Jens


    Jens Weidmann

    Freitag, 15. April 2016 12:44
  • Hallo,

    also ist deine Eklärung nicht so ganz logisch, bzw. falsch, denn dan kommen also auch A5, A7 und A9 in eine Datei (18+13+9=40 also <=40) und A10 in eine weitere Datei.

    Das macht es natuelich schwerer zu helfen wenn die Ziele unzulaenglisch beschrieben sind.

    Beste Gruesse
    brima



    • Bearbeitet brima Freitag, 15. April 2016 14:38
    Freitag, 15. April 2016 12:50
  • Hallo,

    so habe mal zwischendurch ein wenig gebastelt, das Ganze kann man noch optimieren und es wird auch nicht beachtet wenn ein User alleine einen Wert > 40 hat, geht aus deinen Infos nicht heervor ob es sowas gibt ...

    Es funktioniert

    $Werte = Import-Csv .\xxx.csv
    $i = 0
    $j = 1
    $UserSumme = 0
    $ArrayBearbeitet = New-Object System.Collections.ArrayList
    Do {
    	if ((($UserSumme + $Werte[$i].Wert) -le 40) -and (-not ($ArrayBearbeitet.Contains($i)))) {
    		$UserSumme += $Werte[$i].Wert
    		$Null = $ArrayBearbeitet.Add($i)
    		$Werte[$i] | export-csv ".\zzFile-$j.csv" -append  -NoTypeInformation
    	}
    	$i++
    	if ($i -eq $Werte.count -and $ArrayBearbeitet.count -lt $Werte.count) {
    		$j++
    		$UserSumme = 0
    		$i = 0
    	}
    } until (($i -ge $Werte.count) -and ($ArrayBearbeitet.count -eq $Werte.count))
    

    Ergebnis:
    zzFile-1.csv
    "User","Wert"
    "A1","20"
    "A2","5"
    "A3","4"
    "A8","10"

    zzFile-2.csv
    "User","Wert"
    "A4","37"

    zzFile-3.csv
    "User","Wert"
    "A5","18"
    "A7","13"
    "A9","8"

    zzFile-4.csv
    "User","Wert"
    "A6","40"

    zzFile-5.csv
    "User","Wert"
    "A10","25"

    Beste Gruesse
    brima

    • Als Antwort markiert Jens0312 Freitag, 15. April 2016 16:32
    Freitag, 15. April 2016 14:24
  • Hi Brima,

    vielen Dank für die Antwort :-) das bringt mich enorm weiter.

    Danke

    Jens


    Jens Weidmann

    Freitag, 15. April 2016 15:02
  • Hallo,

    dann lies mal bitte noch das hier:

    Click

    Danke.

    Beste Gruesse
    brima

    Freitag, 15. April 2016 15:07
  • Hi brima,

    ibesten Dank für eine Antwort ;-)

    ich habe das jetzt mal über meine echtdaten laufen lassen und festgestellt, das meine Werte Commas enthalten.

    Wie geb ich dem skript das mit?

    Danke

    Jens


    Jens Weidmann

    Freitag, 15. April 2016 16:44
  • Hallo,

    ich habe in meinem Beispiel mit Komma als Trennzeichen gearbeitet, du kannst aber beim import-csv wie export-csv mit dem Paramter Delimiter arbeiten um dem System mitzuteilen was das Trennzeichen ist, in deinem Beispiel wäre dies dann -Delimiter ';'

    Die Powershell arbeitet intern "englisch", dort ist das Komma der Punkt, wenn du in der Console z.B.: eingibst

    2,5 + 3,4 erhältst Du nicht das Ergebnis das du erwartest bei 2.5 + 3.4 kommt 5.9 raus, wird aber als 5,9 angezeigt :-) weil hier dann wieder deine Culture Settings greifen.

    Du musst also auf dem Komma ein Punkt machen für die Werte, aus dem Kopf (kann es gerade nicht testen) müsste das so gehen wenn du im Code die Stellen mit

    $Werte[$i].Wert durch [double]($Werte[$i].Wert).replace(',','.') ersetzen, und dann am besten $UserSumme = 0 durch [double]$UserSumme = 0 ersetzen.

    Das sind jetzt alles Grundlagen, deshlab empfehle ich dir ein gute PowerShell Buch, von Tobias Weltner kommt die Tage ein neues auf den Markt, die finde ich recht gut.

    Beste Gruesse
    brima

    Freitag, 15. April 2016 17:26