Powershell CSV replace jeden 2.Fund
Guten Tag liebe Community und Experten,
ich habe aktuell ein Problem bzgl. UTC (Coordinated Universal Time) und der kommenden Zeitumstellung, das ich gerne mittels Powershell lösen würde.
Wir bekommen täglich mehrere CSV Dateien mit viertelstündigen Werten, diese werden mittels Zwischenschritt weiterverarbeitet und final in ein System eingespielt. Die CSV Dateien enthalten nur ein Datum und eine Uhrzeit, aber keine Zeitzonenangabe. Hier ein Ausschnitt einer Bsp. CSV:
Dieser Ausschnitt wiederholt sich mehrere hundert Male, da mehrere Positionen enthalten sind. Ich würde nun gerne mittels Powershell nach den doppelten Zeiteinträgen suchen und jeden 2. Fund ersetzen. Z.B.
Ersetzen durch:
...sodass die CSV wie folgt aussieht:
Allerdings weiß ich nur den Befehl um sämtliche Funde zu finden und zu ersetzen. Gibt es eine Möglichkeit per Schleife und Skip die ersten Funde zu überspringen? Ich habe es mit einer Variablen und Modulo versucht, also es sollen nur Strings replaced werden, wenn Modulo 0 ist und das funktioniert auch, allerdings bin ich gerade zu doof die Ergebnisse inklusive der übrigen CSV Datei in einer Output Datei zu speichern. Hier mein aktueller Code:
Meine daraus resultierende csv Datei, leider ohne Header und andere Zeilen. Ich verstehe auch warum, aber komme aktuell nicht auf die Lösung
Viele Grüße
narthan
ich habe aktuell ein Problem bzgl. UTC (Coordinated Universal Time) und der kommenden Zeitumstellung, das ich gerne mittels Powershell lösen würde.
Wir bekommen täglich mehrere CSV Dateien mit viertelstündigen Werten, diese werden mittels Zwischenschritt weiterverarbeitet und final in ein System eingespielt. Die CSV Dateien enthalten nur ein Datum und eine Uhrzeit, aber keine Zeitzonenangabe. Hier ein Ausschnitt einer Bsp. CSV:
"Datum";"Uhrzeit";"Position";"Wert"
25.10.2020;01:30;A106;22.5
25.10.2020;01:45;A106;22.8
25.10.2020;02:00;A106;23.5
25.10.2020;02:15;A106;9.5
25.10.2020;02:30;A106;5.0
25.10.2020;02:45;A106;3.7
25.10.2020;02:00;A106;26.3
25.10.2020;02:15;A106;22.2
25.10.2020;02:30;A106;20.1
25.10.2020;02:45;A106;19.5
25.10.2020;03:00;A106;15.5
25.10.2020;03:15;A106;9.8
25.10.2020;03:30;A106;4.0
25.10.2020;03:45;A106;3.9
25.10.2020;04:00;A106;20.4
Dieser Ausschnitt wiederholt sich mehrere hundert Male, da mehrere Positionen enthalten sind. Ich würde nun gerne mittels Powershell nach den doppelten Zeiteinträgen suchen und jeden 2. Fund ersetzen. Z.B.
25.10.2020;02:00;A106;26.3
25.10.2020;02:15;A106;22.2
25.10.2020;02:30;A106;20.1
25.10.2020;02:45;A106;19.5
25.10.2020;02:01;A106;26.3
25.10.2020;02:02;A106;22.2
25.10.2020;02:03;A106;20.1
25.10.2020;02:04;A106;19.5
...sodass die CSV wie folgt aussieht:
...
25.10.2020;02:00;A106;23.5
25.10.2020;02:15;A106;9.5
25.10.2020;02:30;A106;5.0
25.10.2020;02:45;A106;3.7
25.10.2020;02:01;A106;26.3
25.10.2020;02:02;A106;22.2
25.10.2020;02:03;A106;20.1
25.10.2020;02:04;A106;19.5
...
Allerdings weiß ich nur den Befehl um sämtliche Funde zu finden und zu ersetzen. Gibt es eine Möglichkeit per Schleife und Skip die ersten Funde zu überspringen? Ich habe es mit einer Variablen und Modulo versucht, also es sollen nur Strings replaced werden, wenn Modulo 0 ist und das funktioniert auch, allerdings bin ich gerade zu doof die Ergebnisse inklusive der übrigen CSV Datei in einer Output Datei zu speichern. Hier mein aktueller Code:
$inputpath = 'C:\Users\XY\csv\'
$outputpath = 'C:\Users\XY\output\'
$datetoday = Get-Date -Format yyyyMMdd
$search1 = "02:00"
$replace1 = "02:01"
$Results = Get-ChildItem $inputpath -Filter *.csv |
Foreach-Object {
$csvPath=$_.FullName
$Filename=$_.BaseName
$outputFile= ($outputpath+$Filename+"_"+$datetoday+".csv")
$e = $null
$n = 0
foreach($e in (Get-Content -Path $csvPath | Where-Object {($_ -like '*02:00*')})) {
$n+=1
if (-not ($n%2)){
$e -replace $search1, $replace1
}
}
}
$Results | Set-Content -Path $outputFile -Encoding UTF8
Meine daraus resultierende csv Datei, leider ohne Header und andere Zeilen. Ich verstehe auch warum, aber komme aktuell nicht auf die Lösung
25.10.2020;02:01;A106;26.3
25.10.2020;02:01;A107;401.1
25.10.2020;02:01;A108;58.0
25.10.2020;02:01;A109;98.7
Viele Grüße
narthan
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 4396706856
Url: https://administrator.de/contentid/4396706856
Ausgedruckt am: 08.11.2024 um 11:11 Uhr
4 Kommentare
Neuester Kommentar
Moin Narthan,
kann es gerade nicht testen, aber sofern ich mich nicht vertippt habe, müsste es so funktionieren:
Gruß Thomas
kann es gerade nicht testen, aber sofern ich mich nicht vertippt habe, müsste es so funktionieren:
$inputpath = 'C:\Users\XY\csv'
$outputpath = 'C:\Users\XY\output'
Foreach ($File in Get-Childitem "$inputpath\*.csv") {
$CSV = Import-CSV -Delimiter ";" -Path $File
Foreach ($Datum in $CSV | Group Datum) {
$i = 1
Foreach ($Zeit in $Datum.Group | Group Uhrzeit | Where Count -gt 1) {
$Zeit.Group[1].Uhrzeit = (Get-Date $Zeit.Group[1].Uhrzeit -Format "HH:")+$i.ToString("d2")
$i++
}
}
$CSV | Export-Csv -NoTypeInformation -Delimiter ";" ("{0}\{1}" -f $outputpath,$File.name)
}
Gruß Thomas
Zitat von @narthan:
Kannst du mir bitte noch die Zeile erklären, die verstehe ich nicht so ganz:
$Time ist jeweils eine Gruppe aus Zeilen, bei der Datum und Uhrzeit gleich sind.Kannst du mir bitte noch die Zeile erklären, die verstehe ich nicht so ganz:
$Time.Group[1].Time = (Get-Date $Time.Group[1].Time -Format "HH:")+$i.ToString("d2")
.Group[1] gibt von dieser jeweils die 2. Zeile (also index 1) aus
.Uhrzeit ist die Spalte Uhrzeit aus dieser Zeile.
Diese wird neu gesetzt. Die Stunden bleiben ja, also habe ich mit Get-Date ein datetime-objekt erzeugt und über -Format "HH:" nur noch die Stunden und den Doppelpunkt ausgegeben.
Alternativ hätte man hier natürlich auch mit .Substring(0,3) arbeiten können.
Was jetzt noch fehlt sind also die Minuten - diese kommen aus der aufsteigenden Integervariable $i. Diese wird mit .ToString("d2") 2-stellig ausgegeben.
Gruß Thomas