115129
Goto Top

BATCH - Zeile(n) aus Log-Datei in eine Archiv-Datei nur wenn nicht vorhanden einlesen

Hallo,

dieser Einzeiler fügt mir Zeile für Zeile den Inhalt von d:\log in d:\archiv.txt untereinander ein.

Log-to-Archiv.bat
type "d:\log">>"d:\archiv.txt"  

Was muss geändert werden, wenn in d:\archiv.txt eine Zeile nur einmal vorkommen darf?
Jede Zeile ist einmalig, da Zeitstempel am Zeilenanfang enthalten sind.

Der Aufbau einer Zeile sieht so aus:
2014.06.15 - 14:22:11 | Benutzer: Admin | Zähler: 5 | VPN: irgendeintextmitzahlen

Im Moment habe ich lediglich das Problem, dass mir z.B. die oben aufgeführte Zeile mehrfach nach d:\archiv.txt geschrieben wird.
Es soll ein Vergleich zuvor stattfinden ob diese oder jene Zeile aus d:\log in d:\archiv.txt besteht; wenn nein -> schreibe Zeile, wenn ja -> schreibe die Zeile nicht.

Besten Dank schon mal.

Gruß,
Blattlaus

Content-Key: 240953

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

Printed on: April 18, 2024 at 21:04 o'clock

Member: bastla
bastla Jun 15, 2014 at 18:11:45 (UTC)
Goto Top
Hallo BlattlausOG!

Ungetestet etwa so:
findstr /vg:"d:\archiv.txt" "d:\log">>"d:\archiv.txt"
Grüße
bastla
Member: Endoro
Endoro Jun 15, 2014 at 18:16:15 (UTC)
Goto Top
Hey,
ich würde das mit uniq machen (aus den GNUWin32-Tools)
sort log.txt | uniq > archiv.txt

wenn es denn unbedingt Batch sein soll (umgetestet):
for /f "delims=" %%a in (log.txt) do set "line.%%a=7"  
for /f "tokens=1*delims=." %%a in ('set line.') do (  
   for /f "tokens=1*delims=="%%c in ("%%~b") do echo(%%c  
)>archiv.txt

Gruss, Endoro.
Mitglied: 115129
115129 Jun 15, 2014 updated at 19:54:56 (UTC)
Goto Top
Hallo zusammen,

vielen Dank für die ultraschnelle Antwort.

Ich habe beide Varianten getestet:

@bastla:
Habe den Einzeiler mit in meine Batch eingetragen, bekomme jedoch eine Meldung dass die Zeichenfolge der "Archiv-Datei" nicht gelesen werden konnte.

@Endoro:
Habe deine zweite Variante getestet, diese scheint mir in der zweiten Zeile abzubrechen:
for /f "tokens=1*delims=." %%a in ('set line.') do (  

Kurze Frage...
%%a %%b %%c sind nur Variabeln, die könnte man auch in z.B. %%x %%y %%z umbenennen, oder?

Noch eine Idee?

Besten dank face-smile

Gruß,
Blattlaus
Member: Endoro
Solution Endoro Jun 16, 2014 updated at 11:45:11 (UTC)
Goto Top
Versuch es mal so:
for /f "usebackqdelims=" %%a in ("log.txt") do set ".%%a=7"  
(for /f "tokens=1*delims==." %%a in ('set .') do echo(%%a  
)>archiv.txt
Es funktioniert allerdings nicht für Zeilen mit = im Text.

Die Lösung von bastla könnte so funktionieren:
>"d:\archiv.txt" break  
findstr /vg:"d:\archiv.txt" "d:\log">>"d:\archiv.txt"  
Das scheint nicht mit allen Windows-Versionen zu funktionieren, zB nicht mit XP.

Gruss, Endoro.
Member: bastla
Solution bastla Jun 16, 2014 updated at 11:45:09 (UTC)
Goto Top
Hallo BlattlausOG!

Sollte dann so gehen:
move "d:\archiv.txt" "d:\archiv.bak"  
findstr /vg:"d:\archiv.bak" "d:\log">"d:\archiv.txt"  
Die bak-Datei kannst Du als Sicherungskopie betrachten oder auch gleich wieder löschen.

Grüße
bastla
Mitglied: 115129
115129 Jun 16, 2014 at 11:44:47 (UTC)
Goto Top
Hallo Endoro,
Hallo Bastla,

vielen Dank für Eure Unterstützung.

@Endoro:
Ich habe deinen Code getestet aber zuvor in der letzten Zeile > nach >> geändert. Ich will das vorhandene nicht überschreiben.
for /f "usebackqdelims=" %%a in ("log.txt") do set ".%%a=7"  
(for /f "tokens=1*delims==." %%a in ('set .') do echo(%%a  
)>>archiv.txt
Leider schreibt er mir nur:
2014.
...mehrfach untereinander.

Nicht so schlimm, habe ja noch den Vorschlag von Bastla face-smile

@bastla:
Deinen habe ich ebenfalls getestet, das funktioniert soweit. Allerdings gefällt es mir nicht richtig, dass eine separate Datei angelegt wird, da sich der Batch-Vorgang all 2 Minuten wiederholt.
In der letzten Zeile wird die Datei d:\archiv.bak gelöscht.
move "d:\archiv.txt" "d:\archiv.bak"  
findstr /vg:"d:\archiv.bak" "d:\log">"d:\archiv.txt"  
del "d:\archiv.bak"  

So, dann danke ich euch beiden nochmals für die tatkräftige Unterstützung...ihr werdet wieder von mir hören face-smile

Schöne Grüße,
Blattlaus
Mitglied: 115129
115129 Jun 17, 2014 updated at 12:01:06 (UTC)
Goto Top
Hallo,

ich muss mich noch einmal melden bzgl. meines Anliegens.
Es scheint doch noch nicht so zu funktionieren, wie ich es gerne hätte.

Mein Vorhaben:
Es soll der Inhalt der D:\log nach D:\archiv.txt kopiert werden, wobei der Inhalt der D:\log immer bestehen bleibt.
Kommen neue Zeilen der D:\log hinzu, sollen "nur" diese nach D:\archiv.txt kopiert und angereiht werden (Vergleich).
Nach jeder Skriptausführung soll zuguterletzt der Inhalt der D:\archiv.txt alphabetisch sortiert werden.

Beispielzeile der D:\log:
2014.06.15 14:22:11 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla

Mein derzeitiger Code, wo im Moment nichts passiert (hatte es mal geschafft dass er die Zeilen mehrfach einliest):
copy "D:\log" "D:\log.bak"  
copy "D:\archiv.txt" "D:\archiv.bak"  
findstr /vg:"D:\log.bak" "D:\archiv.bak">"D:\archiv.txt"  
sort "\archiv.bak" /O "D:\archiv.txt"  
del "D:\log.bak"  
del "D:\archiv.bak"  

Würde mir nochmals jemand unter die Arme greifen? face-smile

Vieeelen Dank.
Member: bastla
bastla Jun 17, 2014 at 15:31:01 (UTC)
Goto Top
Hallo BlattlausOG!
wo im Moment nichts passiert
trifft es nicht ganz - es wird ja eine neue "archiv.txt" mit den den zusätzlichen Zeilen erzeugt, aber dann in Zeile 4 wieder durch die alte Version ("archiv.bak") überschrieben - daher (ungetestet) eher:
copy "D:\archiv.txt" "D:\archiv.neu"  
findstr /vg:"D:\log" "D:\archiv.txt">>"D:\archiv.neu"  
sort "D:\archiv.neu" /O "D:\archiv.txt"  
del "D:\archiv.neu"  
Grüße
bastla
Mitglied: 115129
115129 Jun 17, 2014 updated at 21:34:58 (UTC)
Goto Top
Hallo Bastla,

danke für deine Antwort.

Ich habe es eben getestet und dasselbe Phänomen wie zuvor.
In archiv.txt wird nichts geschrieben, sie bleibt leer obwohl 13 Zeilen in log enthalten sind. Man sieht, dass an/in der archiv.txt was passiert, das Änderungsdatum der Datei ändert sich jedes Mal.

Nochmal der Ablauf:
Batch wird ausgeführt -> Vergleich ob in log eine Zeile existiert die nicht in archiv.txt enthalten ist -> Zeile in Archiv.txt nicht enthalten, kopiere diese / Zeile in Archiv.txt enthalten , nichts tun -> archiv.txt alphabetisch sortieren -> log erhält von einem externen Programm neue Zeilen (ebenso unterschiedlich allein durch enthaltener Zeitstempel) dazu -> Batch wird ausgeführt -> usw. usw.

In den Zeilen sind ebenso folgende Zeichen enthalten, ich hoffe diese stören nicht die findstr-Funktion:
| ( ) _ - @ . : /

Gäbe es noch ne Alternative?

Gruß,
Blattlaus


EDIT:

Ich habe nun rumgespielt und es läuft...naja, zumindest im jetzigen Augenblick. Mal sehen wie es in ein paar Tage ausschaut.

Code:
copy "D:\archiv.txt" "D:\archiv.neu"  
for /f "delims=" %%a in (D:\log) do findstr /i /X /C:"%%a" D:\archiv.txt || echo %%a>>D:\archiv.neu  
sort "D:\archiv.neu" /O "D:archiv.txt"  
del "D:\archiv.neu"  

Danke und bis zum nächsten mal face-smile

Gruß,
Blattlaus
Member: Endoro
Endoro Jun 18, 2014 updated at 01:46:52 (UTC)
Goto Top
Müsste auch so gehen:
@echo off &setlocal
for /f "usebackqdelims=" %%a in ("log.txt") do set ".%%a=7"  
for /f "usebackqdelims=" %%a in ("archiv.txt") do set ".%%a=7"  
(for /f "tokens=1*delims==." %%a in ('set .') do echo(%%a  
)>"archiv.txt"  
Gruss, Endoro.
Mitglied: 115129
115129 Jun 18, 2014 updated at 05:25:17 (UTC)
Goto Top
Guten Morgen Endoro,

habe dein Code getestet, allerdings werden die Zeilen nicht richtig geschrieben.

So sollten die Zeilen ausschauen:
2014.06.16 14:22:11 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla/...
2014.06.17 14:23:24 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla/...
2014.06.18 14:25:15 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla/...
2014.06.19 14:45:15 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla/...
2014.06.20 14:51:12 | Benutzer: blabla | Zähler: blabla | Pfad: /blabla/blabla/blabla/...

So werden Sie durch den Code geschrieben:
2014
2014
2014
2014
2014

Danke und Gruß,
Blattlaus
Member: Endoro
Solution Endoro Jun 18, 2014 updated at 11:28:10 (UTC)
Goto Top
Stimmt! Danke, besser wäre dieses:
@ECHO OFF &SETLOCAL disableDelayedExpansion
for /f "usebackqdelims=" %%a in ("log.txt") do set ".%%a=7"  
FOR /f "usebackqdelims=" %%a in ("archiv.txt") do set ".%%a=7"  
(FOR /f "tokens=1*delims==" %%a in ('set .') do (  
	FOR /f "tokens=*delims=." %%c IN ("%%~a") DO echo(%%c  
))>"archiv.txt"  
Nun könnte es eventuell noch Probleme mit der Codepage geben (Darstellung der Umlaute).
Gruss, Endoro
Mitglied: 115129
115129 Jun 18, 2014 at 11:28:05 (UTC)
Goto Top
Hi Endoro,

hab es getestet und es scheint zu funktionieren.

Ich werde deine Zeilen die nächsten Tage anwenden und melde mich nochmal wenns noch zu weiteren Problemen kommen sollte.

Besten Dank und auf bald.

Gruß,
Blattlaus
Mitglied: 115129
115129 Jun 20, 2014 updated at 15:06:04 (UTC)
Goto Top
Hallo zusammen,

ich bräuchte nochmals Unterstützung, um mein Vorhaben zu optimieren. Zu Testzwecken kommt diese Anpassung zum Einsatz.

Der gewünschte Ablauf:

Im Moment wende ich folgenden Code an...
@ECHO OFF &SETLOCAL disableDelayedExpansion
for /f "usebackqdelims=" %%a in ("log.txt") do set ".%%a=7"  
FOR /f "usebackqdelims=" %%a in ("archiv.txt") do set ".%%a=7"  
(FOR /f "tokens=1*delims==" %%a in ('set .') do (  
	FOR /f "tokens=*delims=." %%c IN ("%%~a") DO echo(%%c  
))>"archiv.txt"  
...dieser Code funktioniert einwandfrei, nur die Sortierung sollte wie folgt aussehen (jüngster Zeitstempel in ertse Zeile):
2014.06.17 15:22:11 | Benutzer: Achim | Zähler: 1 | Pfad: /blabla/blabla/blabla
2014.06.17 14:23:11 | Benutzer: Uwe | Zähler: 1 | Pfad: /blabla/blabla
2014.06.15 14:24:11 | Benutzer: Bert | Zähler: 1 | Pfad: /blabla/blabla/blabla
2014.06.14 14:24:11 | Benutzer: Olaf | Zähler: 1 | Pfad: /blabla
...
...ist dass dann der Fall, kann die eigendliche Anpassung stattfinden.

Batch ausführen -> Zeilen der log.txt auslesen und mit archiv.txt vergleichen -> existiert der "PFAD" in archiv.txt nicht, komplette Zeile verschieben / existiert der "PFAD" in archiv.txt, den Wert von log.txt mit dem Wert aus archiv.txt addieren und überschreiben -> Inhalt der archiv.txt sortieren -> Inhalt der log.txt und log.temp.txt (eine tempöräre Datei eines Programms) leeren.
So sollte die Ausgabe aussehen:
2014.06.17 15:22:11 | Benutzer: Achim | Zähler: 2 | Pfad: /blabla/blabla/blabla
2014.06.17 14:23:11 | Benutzer: Uwe | Zähler: 1 | Pfad: /blabla/blabla
2014.06.15 14:24:11 | Benutzer: Bert | Zähler: 2 | Pfad: /blabla/blabla/blabla
2014.06.14 14:24:11 | Benutzer: Olaf | Zähler: 1 | Pfad: /blabla
...

Hat hierfür jemand eine Lösung?

Vielen Dank wieder einmal vorab face-smile

Gruß.
Blattlaus
Member: Endoro
Endoro Jun 20, 2014 at 18:40:19 (UTC)
Goto Top
Hey,
ich verstehe deine Erklärung leider nicht.
Wohin wird was verschoben?
Was wird addiert?
Was bedeutet es, eine Datei zu "leeren"?
Gruss, Endoro
Mitglied: 115129
115129 Jun 20, 2014 updated at 23:56:42 (UTC)
Goto Top
Hi Endoro,

erneuter Versuch face-smile

Benutzer:
Zähler:
Pfad:
...sind statische Namen die sich nie ändern, dahinter jedoch folgen Variablen welche verglichen werden müssen.

Funktionsweise:
1. Batch wird ausgeführt
2. Zeilen der log.txt einlesen
3. Suche nach Stichwörter in log.txt die am Scriptanfang frei definiert werden können, wenn gefunden lösche komplette Zeile in log.txt (unter Stichwörter fallen einzelne Wörter ohne Umlaute oder Sonderzeichen)
4. Existiert der aus der log.txt eingelesene Pfad: (z.B. /blabla/blabla/blabla) in archiv.txt nicht, komplette Zeile nach archiv.txt kopieren oder verschieben.
Existiert der Pfad: (z.B. /blabla/blabla/blabla) irgendwo in archiv.txt, dann den Zähler-Wert von log.txt mit dem Zähler-Wert aus archiv.txt addieren bzw. zusammenzählen (siehe "Zähler" und "Pfad" in Ausgabe weiter unten) und den Zähler-Wert in Archiv.txt mit dem Ergebnis überschreiben (alle Zähler-Werte in der Zeile wo z.B. der Pfad: /blabla/blabla/blabla vorkommt)
5. Inhalt der archiv.txt sortieren (jüngster Zeitstempel in erste Zeile)
6. Inhalt der log.txt und log.temp.txt (eine tempöräre Datei eines Programms) löschen.

So sollte die Ausgabe aussehen in archiv.txt:
2014.06.17 15:22:11 | Benutzer: Achim | Zähler: 2 | Pfad: /blabla/blabla/blabla
2014.06.17 14:23:11 | Benutzer: Uwe | Zähler: 1 | Pfad: /blabla/blabla
2014.06.15 14:24:11 | Benutzer: Bert | Zähler: 2 | Pfad: /blabla/blabla/blabla
2014.06.14 14:24:11 | Benutzer: Olaf | Zähler: 1 | Pfad: /blabla
...

Hoffe es ist etwas verständlicher und nicht zu aufwändig...

Gruß,
Blattlaus
Member: Endoro
Endoro Jun 20, 2014 at 22:57:27 (UTC)
Goto Top
Hey,
Was soll in 2. verglichen werden und was ist die Konsequenz aus dem Vergleich?
Wie können die Stichwörter in 3. aussehen (Beispiele).

(alle Zähler-Werte in der Zeile wo der Pfad: /blabla/blabla/blabla vorkommt)
Was ist damit gemeint? Die Variable Pfad ist eindeutig.

5. Wonach sortieren? Aufwärts oder abwärts?

Das wächst sich zu einem Projekt aus.
Leider muss ich zu allem, was ich an der Backe habe, auch noch in Urlaub fahren.
Wenn dich dies alles in 2 Wochen noch interessiert, erstelle einen Testdatensatz.
Gruss, Endoro
Mitglied: 115129
115129 Jun 20, 2014 at 23:45:49 (UTC)
Goto Top
Hallo Endoro,

Urlaub, na das hört sich doch gut an!

Leider muss ich zu allem, was ich an der Backe habe, auch noch in Urlaub fahren.
Entweder verstehe ich das falsch, oder du "musst" in Urlaub fahren...na ich würde sofort tauschen face-smile

Mach dir kein Stress, ist für mich eh nur zum testen und somit eilt es nicht.

Danke dir trotzdem für die großartige Unterstützung und wünsche schöne Urlaubstage.

Gruß,
Blattlaus