Powershell - .txt Datei auslesen und Wert ausgeben
Hallo Community,
Meine Codezeilen:
Einfach übersetzt:
Vergleiche die Werte in der DateiA.
- Wenn die Werte übereinstimmen, schreib in die Error.txt "Die Datenlöschung war erfolgreich"
- Wenn die Werte nicht übereinstimmen, such in der Datei nach "Warnung" und gib die Zeile in der Error.txt aus
Das Gleiche gilt für DateiB
Meine Frage:
Ich möchte dass wenn die Werte nicht übereinstimmen und er KEIN "Warnung" in der DateiX findet, dass er dann nochmal in der DateiC nach "Warnung" sucht und die Zeile dann auch in der Error.txt-Datei ausgibt.
An welcher Stelle muss ich das ergänzen und was genau muss ergänzt werden ?
Ich hoffe das war sinnvoll erläutert.
Vielen Dank für die Antworten.
Meine Codezeilen:
$DateiA=Get-content -Path ("C:\Benutzer\Datenlöschung_A_"+(get-date).ToString(‘yyyyMMdd’)+"*.txt")
$DateiB=Get-content -Path ("C:\Benutzer\Datenlöschung_B_"+(get-date).ToString(‘yyyyMMdd’)+"*.txt")
$DateiC=Get-content -Path ("C:\Benutzer\Datenlöschung\Neuer Ordner\loeschen-C-"+(get-date).ToString(‘dd.MM.yyyy’)+"*.txt")
[int]$löschen_A = ($DateiA -match '^# Anzahl zu löschender Dateien: ') -replace '.*\D(?=\d+$)'
[int]$gelöscht_A = ($DateiA -match '^# Anzahl gelöschter Dateien : ') -replace '.*\D(?=\d+$)'
[int]$löschen_B = ($DateiB -match '^# Anzahl zu löschender Dateien: ') -replace '.*\D(?=\d+$)'
[int]$gelöscht_B = ($DateiB -match '^# Anzahl gelöschter Dateien : ') -replace '.*\D(?=\d+$)'
if ($löschen_A -ne $gelöscht_A) { $DateiA -match 'Warnung' | set-content Error.txt}
if ($löschen_A -eq $gelöscht_A) {"Datenlöschung_A_"+(get-date).ToString(‘yyyyMMdd’)+".txt: Die Datenlöschung war erfolgreich" | Set-Content Error.txt}
if ($löschen_B -ne $gelöscht_B) {$DateiB -match 'Warnung' | Add-content Error.txt}
if ($löschen_B -eq $gelöscht_B) {"Dateilöschung_B_"+(get-date).ToString(‘yyyyMMdd’)+".txt: Die Datenlöschung war erfolgreich" | Add-Content Error.txt}
Einfach übersetzt:
Vergleiche die Werte in der DateiA.
- Wenn die Werte übereinstimmen, schreib in die Error.txt "Die Datenlöschung war erfolgreich"
- Wenn die Werte nicht übereinstimmen, such in der Datei nach "Warnung" und gib die Zeile in der Error.txt aus
Das Gleiche gilt für DateiB
Meine Frage:
Ich möchte dass wenn die Werte nicht übereinstimmen und er KEIN "Warnung" in der DateiX findet, dass er dann nochmal in der DateiC nach "Warnung" sucht und die Zeile dann auch in der Error.txt-Datei ausgibt.
An welcher Stelle muss ich das ergänzen und was genau muss ergänzt werden ?
Ich hoffe das war sinnvoll erläutert.
Vielen Dank für die Antworten.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 665708
Url: https://administrator.de/contentid/665708
Ausgedruckt am: 24.11.2024 um 02:11 Uhr
13 Kommentare
Neuester Kommentar
Moin,
Für sowas gibt es else. So braucht der Wert nur einmal geprüft zu werden.
tio.run
Gruß Thomas
Für sowas gibt es else. So braucht der Wert nur einmal geprüft zu werden.
Ich möchte dass wenn die Werte nicht übereinstimmen und er KEIN "Warnung" in der DateiX findet, dass er dann nochmal in der DateiC nach "Warnung" sucht und die Zeile dann auch in der Error.txt-Datei ausgibt.
if ($löschen_A -ne $gelöscht_A) {
if ( $DateiA | Where-Object { $_ -match '^.*warnung.*$' } ) { $Matches.0 | Set-Content Error.txt }
else { $DateiC | Where-Object { $_ -match '^.*warnung.*$' } | %{ $Matches.0 | Set-Content Error.txt } }
}
else {"Datenlöschung_A_"+(get-date).ToString(‘yyyyMMdd’)+".txt: Die Datenlöschung war erfolgreich" | Set-Content Error.txt}
Gruß Thomas
Zitat von @Paul123:
Gibt es eine einfache Möglichkeit der "error.txt" einen Timestamp im Namen zu verpassen?
Kinderspiel, einfach Error.txt durch folgendes ersetzen:Gibt es eine einfache Möglichkeit der "error.txt" einen Timestamp im Namen zu verpassen?
"error_$(Get-Date -f 'yyyy-MM-dd').txt"
Da dann bei einer täglichen Routine jeden Tag eine neue error.txt erstellt werden würde, würde ich dann auch gerne ein Limit von 7 Tagen einbauen.
Ungefähr:
Wenn eine Datei in dem Ordner älter als 7 Tage ist dann lösche diese.
Ungefähr:
Wenn eine Datei in dem Ordner älter als 7 Tage ist dann lösche diese.
Get-Childitem error*.txt | Where-Object LastWriteTime -lt (Get-Date).AddDays(-7) | Remove-Item
Ich hoffe ich nerve mit meinen Fragen nicht.
Würde ich es nicht gerne tun, würde ich es gar nicht tun 😉.Gruß Thomas
Zitat von @Paul123:
habe ich als letzte Zeile unten angefügt - funktioniert aber nicht. Ich habe 8 Dateien mit einem fortlaufenden Datum erstellt und trotzdem löscht er dir Dateien nicht.
Richtig, weil der Befehl die Dateien nicht nach dem Datum im Dateinamen löscht, sondern nach dem Letzen Änderungsdatum der Dateien.habe ich als letzte Zeile unten angefügt - funktioniert aber nicht. Ich habe 8 Dateien mit einem fortlaufenden Datum erstellt und trotzdem löscht er dir Dateien nicht.
Wenn du das Ganze testen willst, gehe im Explorer in den Ordner, wo die Dateien hin sollen, klicke Oben auf "Datei", wähle "Windows Powershell öffnen" und führe dort folgende Zeile aus:
0..9 | %{$d=(Get-Date).AddDays(-$_);$f=ni -f "error_$($d.Tostring('yyyy-MM-dd')).txt";set-Itemproperty $f LastWriteTime $d}
Set-Content überschreibt immer die komplette Datei.
Eine Zeile an eine vorhandene Datei anfügen geht
Hinweis: Der Vorteil von Set-Content ist, dass die Datei immer vollständig zu Ende geschrieben wird. Wenn also noch andere Programme oder Skripte auf diese Datei zugreifen, können diese so nicht dazwischen funken.
Ich würde die Überprüfung bereits vor dem Anlegen der Error-Datei durchführen.
Wenn du einfach nur die Ganze Datei durchsuchen möchtest, lass das Where-Object einfach weg
Eine Zeile an eine vorhandene Datei anfügen geht
- entweder mit Add-Content
- oder mit Out-File und dem zusätzlichen Parameter -Append
Hinweis: Der Vorteil von Set-Content ist, dass die Datei immer vollständig zu Ende geschrieben wird. Wenn also noch andere Programme oder Skripte auf diese Datei zugreifen, können diese so nicht dazwischen funken.
Und kann ich das denn überhaupt in diesem einem Script so abbilden? Dass erst die Datei erstellt wird und dann nochmal überprüft?
Man kann so ziemlich alles abbilden. Allerdings stelle ich hier die Sinnhaftigkeit mal infrage, erst eine Datei schreiben zu lassen und diese hinterher wieder einzulesen und zu überprüfen.Ich würde die Überprüfung bereits vor dem Anlegen der Error-Datei durchführen.
Ich habe es so versucht:
In diesem Fall wird die error.txt immer überschrieben, egal ob das Wort "Warnung" drin vorkommt oder nicht. Das ist aber nicht Sinn der Sache.
Liegt daran, dass du mit Where-Object die Datei Zeilenweise durchsuchst - es gibt ja allerdings immer Zeilen ohne Warnung, daher ergibt das If-Statement auch immer $true.$datei=Get-Content -Path ("C:\Pfad\zurDatei\error_"+$(Get-Date -f 'dd.MM.yyyy')+".txt")
if ( $datei | Where-Object { $_ -notmatch '^.*warnung*$' } ) { "Die Datenlöschung war vollständig O.K" | Set-Content "error_$(Get-Date -f 'dd.MM.yyyy').txt" }
Wenn du einfach nur die Ganze Datei durchsuchen möchtest, lass das Where-Object einfach weg
if ( $datei -notmatch 'warnung' ) { "Die Datenlöschung war vollständig O.K" | Add-Content "error_$(Get-Date -f 'dd.MM.yyyy').txt" }
Zitat von @Paul123:
Wenn es eine Bessere Lösung gibt, vielleicht zum Beispiel eine 2. TXT-Datei dann bin ich dafür offen.
Wenn es eine Bessere Lösung gibt, vielleicht zum Beispiel eine 2. TXT-Datei dann bin ich dafür offen.
# Datei für Fehlerausgabe
$Ausgabe = "Error_$(get-date -f 'yyyy-MM-dd').txt"
# Für jede Textdatei
Foreach ($File in (Get-Childitem "C:\Benutzer\Datenlöschung*.txt")) {
# Datei lesen
$Content = Get-Content $File
# Werte laden
[int]$löschen = ($Content -match '^# Anzahl zu löschender Dateien: ') -replace '.*\D(?=\d+$)'
[int]$gelöscht = ($Content -match '^# Anzahl gelöschter Dateien : ' ) -replace '.*\D(?=\d+$)'
# Wenn Werte nicht übereinstimmen, Zeile zur Fehlervariable hinzufügen
if ($löschen -ne $gelöscht) { [Array]$Fehler += "Warnung: Die Werte in '$File' stimmen nicht überein!" }
} # Ende der Foreach-Schleife
# Falls die Fehlervariable existiert, schreibe die Fehler in die Ausgabe-Datei, sonst Schreibe alles OK.
If ($Fehler) { $Fehler | Set-Content $Ausgabe }
else { "Die Datenlöschung war vollständig O.K" | Set-Content $Ausgabe }
Zitat von @Paul123:
Wie kann ich ihm denn sagen, dass er alle Zeilen die ein "Warnung" enthalten untereinander in der Error.txt ausgeben soll?
Dann so:Wie kann ich ihm denn sagen, dass er alle Zeilen die ein "Warnung" enthalten untereinander in der Error.txt ausgeben soll?
if ($löschen_A -ne $gelöscht_A) {
if ( $DateiA -match 'Warnung' ) { $DateiA -match 'Warnung' | Set-Content Error.txt }
elseif ( $DateiC -match 'Warnung' ) { $DateiC -match 'Warnung' | Set-Content Error.txt }
}
else {"Datenlöschung_A_"+(get-date).ToString(‘yyyyMMdd’)+".txt: Die Datenlöschung war erfolgreich" | Set-Content Error.txt}
Wieso löschst du die Daten eigentlich in einer seperaten Instanz? Es wäre doch einfacher, gleich während der Datenlöschung meckern zu lassen, wenn er ein Element nicht löschen konnte - und vorallem wieso er es nicht konnte.
Zitat von @Paul123:
1. Frage dazu:
Gibt es die Möglichkeit wenn mir die Zeile mit "Warnung" in meiner Error.txt ausgegeben wird diese durch den Dateinamen zu ergänzen?
Sicher. Willst du das dann für jede Zeile mit Warnung... oder Pro Datei je einmal?1. Frage dazu:
Gibt es die Möglichkeit wenn mir die Zeile mit "Warnung" in meiner Error.txt ausgegeben wird diese durch den Dateinamen zu ergänzen?
Pro Zeile:
($DateiA -match 'Warnung' | %{ "DateiA: $_" }),"" | sc Error.txt
% | ist ein Alias für Foreach-Object |
sc | ist ein Alias for Set-Content |
Je Datei:
"DateiA:",($DateiA -match 'Warnung'),"" | sc Error.txt
2. Frage:
Wie füge ich am Ende einer Ausgabe ein Absatz hinzu? Ich habe es mit `n probiert aber das hat bei mir mal wieder nicht funktioniert
Du musst strikt unterscheiden zwischen...Wie füge ich am Ende einer Ausgabe ein Absatz hinzu? Ich habe es mit `n probiert aber das hat bei mir mal wieder nicht funktioniert
- Einem Raw-Text: Dieser ist quasi wie eine 1-zeilige-Zeichenkette - und kann Zeilenumbruchzeichen ("`n") enthalten, die ein Texteditor später als Umbruch interpretiert.
- Einem Array: Ein echter, Mehrzeiliger Text.
Beispel:
# Raw-Text mit 2-Zeilen:
"Zeile1`nZeile2"
# Array aus 2-Zeilen
"Zeile1","Zeile2"
Zurück zu deinem Fall:
Du liest eine Datei mit gc (Alias für Get-Content) ein. Ohne Angabe des Parameters -Raw wird die Datei an den Zeilenumbruchzeichen in einen Array gesplittet. Dies ist für dich von Vorteil, da du aus deiner Textdatei ja nur einzelne Zeilen mit "Warnung" erhalten möchtest.
Entsprechend fügst du eine Leerzeile einfach ein, indem du eine Leere Zeichenkette mit einem Komma anfügst:
$DateiA,""
($DateiA -match "Warnung"),""
Hoffe das war verständlich, ansonsten einfach fragen.