Powershell - Wert aus Get-Content in DateTime konvertieren
Moin zusammen,
Ausgangslage
Es existiert ein Ordner mit ein paar (vielen) CSV-Dateien, der sporadisch um CSV-Dateien des selben Aufbaus ergänzt wird.
Aufbau der CSV (Die Header lauten anders, haben aber dennoch beknackte Texte, z. B. (m³))
Ziel
Diese CSV-Files sollen eingelesen und am Ende in eine "große" CSV geschrieben werden.
Zudem müssen ein paar Konvertierungen durchgeführt werden. Beispielsweise muss das Datum auch als Datumsformat dargestellt werden. Der Bindestrich zwischen Datum und Uhrzeit ist irgendwie Mist.
Ferner muss aus den ganzen Dezimaltrennzeichen "." ein "," werden.
Was ich habe
Mit dem
Das Datum aus der Quelle soll als
RegEx kann ich zwar einigermaßen lesen, Aktiv anwenden aber... sagen wir mal, wir sind uns noch nicht ganz grün . Mit RegEx kann ich vermutlich "irgendwie" das Datum passend konvertieren, da ich ja eigentlich nur den dritten Bindestrich durch ein Leerzechen ersetzen lassen müsste.
Ferner: Wie kann ich die einzelnen Properties ansprechen, wenn ich denen ja quasi den Header geklaut habe?
Wenn ihr mir bei dieser Frage helfen könnten, würde ich zumindest das Thema mit den Dezimaltrennzeichen rasch lösen können. Ich hab nur keine Idee, wie ich auf die Werte zugreifen kann, ohne einen sprechenden Namen zu haben.
Beispielsweise ist wäre es ja so kein Problem, aber die Spalten heißen leider nicht Col3, ...
Bei meinen Recherchen habe ich bisher noch nicht das richtige gefunden. Wobei ich mal behaupte, dass ich schlicht nicht nach den richtigen Begriffen gesucht habe.
Könnt ihr mir hier ein wenig Nachhilfe geben?
Schon mal besten Dank an euch.
P.S. die Quelldateien entstammen einem Messsystem und lassen sich daher nicht modifizieren - das Wäre auch der von mir favorisierte Weg gewesen: Das Übel an der Wurzel anpacken.
Ausgangslage
Es existiert ein Ordner mit ein paar (vielen) CSV-Dateien, der sporadisch um CSV-Dateien des selben Aufbaus ergänzt wird.
Aufbau der CSV (Die Header lauten anders, haben aber dennoch beknackte Texte, z. B. (m³))
Datum/Zeit;Toller Wert2 in (m³);Der Wert3 ist in l/h;Wert4
2022-01-04-06:27:57;327;21.4;8.105006;98
2022-01-05-06:27:57;303;18.3;8.065323;98
...
Ziel
Diese CSV-Files sollen eingelesen und am Ende in eine "große" CSV geschrieben werden.
Zudem müssen ein paar Konvertierungen durchgeführt werden. Beispielsweise muss das Datum auch als Datumsformat dargestellt werden. Der Bindestrich zwischen Datum und Uhrzeit ist irgendwie Mist.
Ferner muss aus den ganzen Dezimaltrennzeichen "." ein "," werden.
Was ich habe
$src = 'd:\tmp\myTests\data\*'
$dst = 'd:\tmp\myTests\TheHoleContent.csv'
$CSVfiles = Get-ChildItem -path $src -Include *.csv
foreach($file in $CSVfiles){
$content = Get-Content -Path $file.FullName |
Select-Object -Skip 1 @{Name = 'Timestamp'; Expression = { [datetime]::ParseExact($_."Datum/Zeit", 'yyyy-MM-dd-HH:mm:ss')}} |
# Der Einfachheit wegen sind die anderen Spalten erstmal unberücksichtigt geblieben
ConvertFrom-CSV -Delimiter ';'
$content
$content | Export-CSV -Path $dst -Append -Delimiter ';'
}
Mit dem
-Skip 1
will ich die ersten Zeilen in den CSV-Files (=Header) übergehen. Dann habe ich aber das Problem, dass meine Properties keine Namen mehr haben.Das Datum aus der Quelle soll als
yyyy-MM-dd HH:mm:ss
später gespeichert werden. Mein obiger Versuch ([datetime]::ParseExact()) ist eigentlich Quatsch, zu der Erkenntnis bin ich schon gekommen. Quatsch aus zwei Gründen: dadurch habe ich nicht das eigentlich gewollte Format und es funktioniert obendrein nichtRegEx kann ich zwar einigermaßen lesen, Aktiv anwenden aber... sagen wir mal, wir sind uns noch nicht ganz grün . Mit RegEx kann ich vermutlich "irgendwie" das Datum passend konvertieren, da ich ja eigentlich nur den dritten Bindestrich durch ein Leerzechen ersetzen lassen müsste.
Ferner: Wie kann ich die einzelnen Properties ansprechen, wenn ich denen ja quasi den Header geklaut habe?
Wenn ihr mir bei dieser Frage helfen könnten, würde ich zumindest das Thema mit den Dezimaltrennzeichen rasch lösen können. Ich hab nur keine Idee, wie ich auf die Werte zugreifen kann, ohne einen sprechenden Namen zu haben.
Beispielsweise ist wäre es ja so kein Problem, aber die Spalten heißen leider nicht Col3, ...
@{Name = 'myValue3'; Expression = { $_.Col3 -replace ".", ","}}
Bei meinen Recherchen habe ich bisher noch nicht das richtige gefunden. Wobei ich mal behaupte, dass ich schlicht nicht nach den richtigen Begriffen gesucht habe.
Könnt ihr mir hier ein wenig Nachhilfe geben?
Schon mal besten Dank an euch.
P.S. die Quelldateien entstammen einem Messsystem und lassen sich daher nicht modifizieren - das Wäre auch der von mir favorisierte Weg gewesen: Das Übel an der Wurzel anpacken.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 3654696465
Url: https://administrator.de/contentid/3654696465
Ausgedruckt am: 18.12.2024 um 12:12 Uhr
2 Kommentare
Neuester Kommentar
Da das Datum ja eh schon fast fertig ist und nur der Bindestrich stört, lohnt es sich fast gar nicht das Teil in ein Datum zu konvertieren, da ja wohl eh nicht damit gearbeitet/gerechnet werden muss reicht ein replace.
Für den Code oben sähe das mit [datetime]::ParseExact aber so aus falls es interessiert
$src = 'd:\tmp\myTests\data'
$dst = 'd:\tmp\TheHoleContent.csv'
$CSVfiles = Get-ChildItem -path $src -File -Filter *.csv
foreach($file in $CSVfiles){
$csv = Get-Content $file | select -Skip 1 | ConvertFrom-CSV -Delimiter ";" -Header 'Spalte1','Spalte2','Spalte3','Spalte4','Spalte5'
foreach($line in $csv){
$line.Spalte1 = $line.Spalte1 -replace '(\d{4}-\d{2}-\d{2})-(\d{2}:\d{2}:\d{2})','$1 $2'
'Spalte3','Spalte4' | %{
$line.$_ = $line.$_ -replace '\.',','
}
}
$csv | export-csv $dst -Delimiter ";" -NoTypeInformation -Encoding UTF8 -Append
}
Mein obiger Versuch ([datetime]::ParseExact()) ist eigentlich Quatsch, zu der Erkenntnis bin ich schon gekommen. Quatsch aus zwei Gründen: dadurch habe ich nicht das eigentlich gewollte Format und es funktioniert obendrein nicht
Weil da der dritte Culture-Parameter fehlt und natürlich die Property auch noch nicht existiert da nur reiner Text .Für den Code oben sähe das mit [datetime]::ParseExact aber so aus falls es interessiert
$line.Spalte1 = [datetime]::ParseExact($line.Spalte1,'yyyy-MM-dd-HH:mm:ss',[cultureinfo]$null).toString('yyyy-MM-dd HH:mm:ss')