alexirimie
Goto Top

Powershell CSV Script zu langsam - single thread zu multi threading

Hallo,

ich brauche bei folgendem Problem Hilfe.

ich habe diesen Script bekommen, funktioniert auch soweit.
nur dass er leider zu langsam ist.
ich habe eine csv mit ca. 10 000 000 Zeilen diese würde mit dem Script ca. 100 min dauern, es sind aber insgesamt 50 csv Dateien zu machen.

aktuell läuft das Script nur single threaded. Könnte man es multi threading umschreiben? habe 64 threads!

cls

$quelle = 'C:\Users\SDIG\Desktop\csv-test\02'  
$ziel = $quelle
$skip = 10
$files = ls $quelle -File -Filter *.ptx
$cnt = 1
foreach($file in $files){
    Write-Progress -Activity "Processing files" -Status "Working on file $cnt from $($files.Count) ($($file.Name))." -PercentComplete (($cnt / $files.Count) * 100)  
    $csv = Import-CSV $file.Fullname -Delimiter " " -Header (1..4)  
    for ($i = $skip ; $i -lt $csv.Count; $i++){ 
        $csv[$i].4 = [math]::Sqrt([decimal]$csv[$i].4)
    }
    ($csv | ConvertTo-CSV -Delimiter " " -NoType | select -skip 1) -replace '"' | sc "$ziel\$($file.Basename)_Alex.ptx"  
    $cnt++
}

großen dank an "SchmitzKatz"
da ich kein Programmierer bin!

die CSVs sehen wie folgt aus falls dass hift:
5084
2083
0.000000 0.000000 0.000000
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
0.999995 -0.003131 0.001084 0.000000
0.003132 0.999995 -0.000873 0.000000
-0.001081 0.000877 0.999999 0.000000
0.001608 -0.001204 -0.013716 1.000000
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0.000000 0.000000 0.000000 0.136721
0.000000 0.000000 0.000000 0.139422
0.000000 0.000000 0.000000 0.111330
0.000000 0.000000 0.000000 0.090822
0.000000 0.000000 0.000000 0.077638
0 0 0 0
0 0 0 0
0.000000 0.000000 0.000000 0.093843
0.000000 0.000000 0.000000 0.127382
0.000000 0.000000 0.000000 0.125933
0.000000 0.000000 0.000000 0.129091

Gruß Alex

Content-Key: 660639

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

Printed on: April 25, 2024 at 12:04 o'clock

Mitglied: 143611
143611 Mar 09, 2021 at 16:19:05 (UTC)
Goto Top
Moin,

falls Euch eine aktuelle Version der Powershell ("core") zur Verfügung steht, könnten die beiden Schleifen parallel ausgeführt werden.
Hab' auch schon feststellen müssen, dass Write-Progress auch ordentlich Zeit kostet, wenn der Fortschritt über große Mengen dargestellt werden soll.
...oder den Inhalt der obersten Schleife als Task .NET-Style ausführen...

Evtl. dauert auch das Import-Csv entsprechend lange(?)

VG
schleeke
Mitglied: 147669
147669 Mar 09, 2021 updated at 17:30:13 (UTC)
Goto Top
Mit Multithreading kannst du das schon etwas beschleunigen, aber wirklich schnell wird das mit PS nicht wirklich auch wenn man noch so optimiert (statt Import-CSV mit Regex Replace foreach -parallel etc. ).

Ich würde das stattdessen gleich mit gawk in der Bash abfackeln , damit ist das in ein paar Sekunden mit nem Oneliner abgefackelt, da kommt die PS nie mit.
find /folder/to/path -type f -name *.ptx | xargs -I{} gawk -i inplace '{if (NR-1 >= 10){print $1,$2,$3,(sqrt($4))}else{print $0}}' {}  
Member: alexirimie
alexirimie Mar 09, 2021 at 17:15:47 (UTC)
Goto Top
hallo,

danke für die Antwort.
bin nicht so fit im Skripten.

wie würde der Skripten mit deiner variante aussehen?

vielen dank.

Gruß Alex
Mitglied: 147669
147669 Mar 09, 2021 at 17:18:30 (UTC)
Goto Top
Zitat von @alexirimie:
wie würde der Skripten mit deiner variante aussehen?
s.o.
Member: alexirimie
alexirimie Mar 09, 2021 at 17:22:31 (UTC)
Goto Top
wie?
Mitglied: 147669
147669 Mar 09, 2021 updated at 17:24:55 (UTC)
Goto Top
Steht doch oben die Zeile fackelt dir ein Verzeichnis mit allen *.ptx Dateien in einem Rutsch ab ...
Der Bash-Einzeiler macht dir eine Datei mit 1 Mio Zeilen innerhalb von 4 Sekunden auf nem 3GHz 8 Kerner.
Member: alexirimie
alexirimie Mar 09, 2021 updated at 17:26:31 (UTC)
Goto Top
in bekomme leider den fehler:

xargs : Die Benennung "xargs" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der   
Pfad korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.
In Zeile:3 Zeichen:44
+ find /folder/to/path -type f -name *.ptx | xargs -I{} gawk -i inplace ...
+                                            ~~~~~
    + CategoryInfo          : ObjectNotFound: (xargs:String) , CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

helpppp

danke

gruß alex
Mitglied: 147669
147669 Mar 09, 2021 updated at 17:30:48 (UTC)
Goto Top
Du solltest die Posts besser lesen, das oben ist Bash kein Powershell! Also zwecklos das in die Powershell zu pasten. Schon wieder Freitag? 🐟
Member: alexirimie
alexirimie Mar 09, 2021 at 17:33:28 (UTC)
Goto Top
dass tut mir soo leid aber Bash ist doch linux oder?
wie führ ich die Zeile in Windows aus?

sorry bin kein Programmierer...

gruß alex
Mitglied: 147669
Solution 147669 Mar 09, 2021 updated at 17:38:18 (UTC)
Goto Top
Zitat von @alexirimie:

dass tut mir soo leid aber Bash ist doch linux oder?
Jepp
wie führ ich die Zeile in Windows aus?
Subsystem for Linux oder cygwin installieren oder ne VM aufsetzen und dann darin ausführen. Oder die Windows Binary besorgen. Viele Wege führen nach Rom.

Bin dann mal wech.