txt Datei Werte vergleichen und neue .txt Datei erstellen
Hallo,
ich habe leider keinerlei Ahnung deswegen meine Frage hier:
Ich benötige eine Batchdatei(Windows) die es mir ermöglicht eine .txt Datei nach genau 2 Zahlen in feststehenden Zeilen zu durchsuchen und zu vergleichen.
Wenn diese Zahlen beide den gleichen Wert haben soll gar nichts passsieren.
Wenn die beiden Zahlen voneinander abweichen, soll in dem Protrokoll weiter nach der Zeile gesucht werden in der "Warnung" steht. Diese Zeile soll dann in eine neue .txt Datei geschrieben werden.
Beispiel.
Datei.txt:
Anzahl roter Autos: 1
Anzahl blauer Autos: 2
"Warnung, es wurde ein blaues Auto mehr gesehen."
-> Diese Warnung soll dann in einer neuen Error.txt ausgegeben werden.
Wie kann ich das einfach und schnell umsetzen?
Vielen Dank für die Hilfe!
ich habe leider keinerlei Ahnung deswegen meine Frage hier:
Ich benötige eine Batchdatei(Windows) die es mir ermöglicht eine .txt Datei nach genau 2 Zahlen in feststehenden Zeilen zu durchsuchen und zu vergleichen.
Wenn diese Zahlen beide den gleichen Wert haben soll gar nichts passsieren.
Wenn die beiden Zahlen voneinander abweichen, soll in dem Protrokoll weiter nach der Zeile gesucht werden in der "Warnung" steht. Diese Zeile soll dann in eine neue .txt Datei geschrieben werden.
Beispiel.
Datei.txt:
Anzahl roter Autos: 1
Anzahl blauer Autos: 2
"Warnung, es wurde ein blaues Auto mehr gesehen."
-> Diese Warnung soll dann in einer neuen Error.txt ausgegeben werden.
Wie kann ich das einfach und schnell umsetzen?
Vielen Dank für die Hilfe!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 663171
Url: https://administrator.de/contentid/663171
Ausgedruckt am: 24.11.2024 um 00:11 Uhr
24 Kommentare
Neuester Kommentar
Moin,
eigentlich macht man sowas heute mit Powershell:
Falls es doch unbedingt Batch sein muss:
Gruß Thomas
eigentlich macht man sowas heute mit Powershell:
$Datei = Get-Content "Datei.txt"
[int]$rot = ($Datei -match '^Anzahl roter Autos') -replace '.*\D(?=\d+$)'
[int]$blau = ($Datei -match '^Anzahl blauer Autos') -replace '.*\D(?=\d+$)'
if ($rot -ne $blau) {$Datei -match '^Warnung' | set-content Error.txt}
Falls es doch unbedingt Batch sein muss:
@echo off
SetLocal EnableDelayedExpansion
for /f "Tokens=1,* Delims=:" %%A in (Datei.txt) do (
if "%%A" equ "Anzahl roter Autos" set rot=%%B
if "%%A" equ "Anzahl blauer Autos" set blau=%%B
set Line=%%A
if "!Line:~0,7!" equ "Warnung" set Warnung=%%A
)
if %rot% neq %blau% echo %Warnung% > Error.txt
Gruß Thomas
Function Comparecars{
[CmdLetBinding()]
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[String]$InputDatei,
[Parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true)]
[String]$Fehlerdatei
)
# lösche alte Fehlerdatei
if (Test-Path -Path $Fehlerdatei) {
rm $Fehlerdatei
}
If (!(Test-path -Path $Inputdatei)) {
"Eingabedatei fehlt!" | out-file -FilePath $Fehlerdatei -NoClobber -Append
exit # vorzeitiger Ausgang
}
# Lese Zeile 1 und 2 der Daten
$DatInhalt = (Get-Content -path "$InputDatei")[0 .. 1]
$Zeile1 = $DatInhalt.Split(":")
$Zeile2 = $DatInhalt[1].Split(":")
# Stelle die Differenz der Produktion fest
$diff = $Zeile1[1] - $Zeile2[1]
# Gebe Differenzen aus
if ($diff -ne 0) {
if ($diff -gt 0) {
"Überschuß "+$Zeile1+": "+$diff | out-file -FilePath $Fehlerdatei -NoClobber -Append
} else {
$Diff = $Diff *-1
"Überschuß "+$Zeile2+": "+$diff | out-file -FilePath $Fehlerdatei -NoClobber -Append
}
}
}
# Aufruf der Function
Comparecars "C:\TEMP\Pseudodaten\prod.txt" "C:\TEMP\Pseudodaten\Error.txt"
Zitat von @Paul123:
Ich verstehe aber nicht was hinter "'^Anzahl blauer Autos') passiert.
Könntest du mir diesen Teil " -replace '.*\D(?=\d+$)'" nochmal bitte erläutern.
Hier werden die Zeilen über Reguläre Ausdrücke ersetzt, sodass nur die hinteren Zahlen übrig bleiben.Ich verstehe aber nicht was hinter "'^Anzahl blauer Autos') passiert.
Könntest du mir diesen Teil " -replace '.*\D(?=\d+$)'" nochmal bitte erläutern.
Um das im einzelnen zu verstehen:
Regex Tutorial
und Quasi als Legende:
Regex Cheat Sheet
Zitat von @Paul123:
Muss ich dazu die Datei noch modifizieren oder sollte ich das eigentlich 1:1 übernehmen können?
Die Dateien liegen beide im selben Ordner.
Nein, dass Skript kann so 1:1 übernommen werden. Nur wenn die Dateien nicht im selben Ordner lägen, müsstest du den Dateinamen in der 1. Zeile zu einem vollständigen Pfad erweitern.Muss ich dazu die Datei noch modifizieren oder sollte ich das eigentlich 1:1 übernehmen können?
Die Dateien liegen beide im selben Ordner.
Wie genau hast du das denn mit Powershell gemacht? Am einfachsten geht es folgendermaßen:
1) Datei als .ps1-Datei abspeichern.
2) Von der Datei eine Verknüpfung machen (Rechtsklick > kopieren und dann Rechtsklick > Verknüpfung einfügen)
3) In den Verknüpfungseigenschaften sollte bei "Verknüpfungsziel" bereits der Pfad zum ps1-Skript stehen. Vor diesem musst du noch powershell -EP ByPass -File ergänzen. Vollständig sollte die Zeile dann so aussehen:
powershell -EP ByPass -File "C:\Pfad\zum\Skript.ps1"
Ausführen tust du dann immer die Verknüpfung.
Funktioniert hier problemlos. Stehen die Zahlen denn komplett am Zeilenende oder folgen darauf noch Leerzeichen?
Könnte auch mit der Textcodierung zusammen hängen. Welchen Ihnalt gibt er für die Variable $Datei aus?
Das "echo" kannst du bei Powershell übrigens weglassen. Einfach nur:
Wenn die Zahlen immer in Zeile 1 und 2 stehen, ginge auch folgendes:
$Datei liefert von der Variable Datei die Zeile mit dem Index 0 (der Index ist eine Nummerierung, beginnend bei 0). Diese wird beim Doppelpunkt in zwei Teile gesplittet und davon der Zweite Teil (also Index 1) in der Variable $zuLöschen gespeichert.
Das Selbe wird der 2. Zeile der Datei gemacht, anschließend müssen nur noch die Zahlen verglichen werden.
Könnte auch mit der Textcodierung zusammen hängen. Welchen Ihnalt gibt er für die Variable $Datei aus?
Das "echo" kannst du bei Powershell übrigens weglassen. Einfach nur:
$Datei
Wenn die Zahlen immer in Zeile 1 und 2 stehen, ginge auch folgendes:
$Datei = Get-Content "Dok.txt"
[int]$zuLöschen = $Datei.Split(':')[1]
[int]gelöscht = $Datei[1].Split(':')[1]
if ($zuLöschen -ne $gelöscht) {$Datei -match '^Warnung' | Set-Content Error.txt}
Das Selbe wird der 2. Zeile der Datei gemacht, anschließend müssen nur noch die Zahlen verglichen werden.
Ja. Ändere einfach Zeile 1 wie folgt ab:
Dann machen auch die Umlaute kein Problem mehr.
$Datei = Get-Content -Encoding utf8 "Dok.txt"
Zitat von @Paul123:
Achso und noch 2 Dinge. In deinem Script sucht er ja nach dem Wort "Warnung" am Anfang einer Zeile (^).
richtig.Achso und noch 2 Dinge. In deinem Script sucht er ja nach dem Wort "Warnung" am Anfang einer Zeile (^).
Das Wort Warnung steht allerdings mitten in der Zeile trotzdem soll er mir genau diese Zeile komplett in die Error.txt-Datei schreiben.
Du kannst das Zirkumflex für den Zeilenanfang natürlich einfach weglassen - dann findet er die Warnung auch, wenn sie mitten in der Zeile steht. Solange das Wort Warnung nur einmal vorkommt kein Problem, falls nicht musst du halt eine andere Lösung finden, wie du die Zeile eindeutig indentifizieren kannst.Zitat von @Paul123:
Du hast "Dok.txt" doppelt in der Zeile. Einmal weglöschen dann läufts.Get-Content : Es wurde kein Positionsparameter gefunden, der das Argument "Dok.txt" akzeptiert.
In C:\Users\Paul Liegmann\Desktop\Neuer Ordner (2)\Test.ps1:1 Zeichen:10
+ $Datei = Get-Content "Dok.txt" -Encoding UTF8 "Dok.txt"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Moin,
Gruß Thomas
Zitat von @Paul123:
Die Datei wird immer mit einer Uhrzeit ausgegeben.
-> Den letzten Teil (Uhrzeit) Will ich bei meiner Suche nicht berücksichtigen. Was muss ich also hier ergänzen:
Sofern immer nur eine Datei / Tag erstellt wird, könntest du einfach einen Wildcard vor die Erweiterung setzenDie Datei wird immer mit einer Uhrzeit ausgegeben.
-> Den letzten Teil (Uhrzeit) Will ich bei meiner Suche nicht berücksichtigen. Was muss ich also hier ergänzen:
$Datei=Get-content ("Datei_"+(get-date).ToString(‘yyyyMMdd’)+".txt") -Encoding UTF8
$Datei=Get-content ("Datei_"+(get-date).ToString(‘yyyyMMdd’)+"*.txt") -Encoding UTF8
Gruß Thomas
Zitat von @Paul123:
Was mache ich hier falsch?
Das Path-Argument muss als zusammenhängende Zeichenkette übergeben werdenWas mache ich hier falsch?
$Datei=Get-content -Path C:\Temp\("Datei_Name_"+(get-date).ToString(‘yyyyMMdd’)+"*.txt") -Encoding String
$Datei=Get-content -Path ("C:\Temp\Datei_Name_"+(get-date).ToString('yyyyMMdd')+"*.txt") -Encoding utf8