Batch - Mehrere Tausend XML Dateien in monatlich neuen Ordnern nach verschiedenen Strings durchsuchen
Die XML Dateien enthalten Kundennummern in XML Tags. Die Anzahl der jeweiligen Kundennummern ist von Interesse.
Hallo,
mal wieder eine kleine Batchaufgabe
Habe schon hier Mehrere Logfiles in einem Ordner nach bestimmten Textinhalten durchsuchen und in anderer LogDatei Dateiname speichern geschaut. Beides ist aber nicht genau das was ich suche.
Details:
Wir bekommen via FTP XML Dateien. Diese landen später in Ordnern mit folgendem Schema: %BlaBla%_old_201011. Für jeden Monat gibt es also einen Ordner. Über den Monat kommen so gerne mal mehr als 6000 XML Dateien zusammen.
Die Dateien heißen immer anders, sind aber was die XML Tags angeht gleich aufgebaut. Der Inhalt der Tags variiert von Kunde zu Kunde. Jede XML enthält auch den Tag <accountnummer>%Kundennummer%</accountnummer>.
Die XML Dateien des Ordners sollen nun z.B: täglich oder wöchentlich (via scheduled Tasks) duchsucht werden. Interessant hierbei ist nun die Häufigkeit der Kundennummern (Pro XML immer genau eine Kundennummer). Ein Suchlauf ergibt also z.B: das Kundennummer 12345 10x gefunden wurde (also in 10 XMLs) und Kundennummer 55555 20x (also in 20 XMLs). Diese Werte sollen besten Falls in eine HTML geschrieben werden, welche eine Tabelle enthält.
Öffnet man die HTML sollen die Kundennummern (und evtl. Kundennamen) dann sauber nebeneinander stehen und darunter die Häufigkeiten im jeweligen Monat.
Ich denke über einen Findstr lässt sich das sicher lösen. Wenn man sich dann merkt bei welcher Datei man beim letzten Suchlauf war muss nicht wieder alles neu gescannt werden und die Zahlen (Häufigkeit) sollten auch stimmen.
Nun die entscheidene Frage - Lösbar?
Grüsse
Hallo,
mal wieder eine kleine Batchaufgabe
Habe schon hier Mehrere Logfiles in einem Ordner nach bestimmten Textinhalten durchsuchen und in anderer LogDatei Dateiname speichern geschaut. Beides ist aber nicht genau das was ich suche.
Details:
Wir bekommen via FTP XML Dateien. Diese landen später in Ordnern mit folgendem Schema: %BlaBla%_old_201011. Für jeden Monat gibt es also einen Ordner. Über den Monat kommen so gerne mal mehr als 6000 XML Dateien zusammen.
Die Dateien heißen immer anders, sind aber was die XML Tags angeht gleich aufgebaut. Der Inhalt der Tags variiert von Kunde zu Kunde. Jede XML enthält auch den Tag <accountnummer>%Kundennummer%</accountnummer>.
Die XML Dateien des Ordners sollen nun z.B: täglich oder wöchentlich (via scheduled Tasks) duchsucht werden. Interessant hierbei ist nun die Häufigkeit der Kundennummern (Pro XML immer genau eine Kundennummer). Ein Suchlauf ergibt also z.B: das Kundennummer 12345 10x gefunden wurde (also in 10 XMLs) und Kundennummer 55555 20x (also in 20 XMLs). Diese Werte sollen besten Falls in eine HTML geschrieben werden, welche eine Tabelle enthält.
Öffnet man die HTML sollen die Kundennummern (und evtl. Kundennamen) dann sauber nebeneinander stehen und darunter die Häufigkeiten im jeweligen Monat.
Ich denke über einen Findstr lässt sich das sicher lösen. Wenn man sich dann merkt bei welcher Datei man beim letzten Suchlauf war muss nicht wieder alles neu gescannt werden und die Zahlen (Häufigkeit) sollten auch stimmen.
Nun die entscheidene Frage - Lösbar?
Grüsse
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 154466
Url: https://administrator.de/forum/batch-mehrere-tausend-xml-dateien-in-monatlich-neuen-ordnern-nach-verschiedenen-strings-durchsuchen-154466.html
Ausgedruckt am: 24.12.2024 um 02:12 Uhr
16 Kommentare
Neuester Kommentar
Hallo BBUser!
Soferne es bereits einen Index aller Kundennummern (als Textdatei "KundenNr.txt" mit jeweils einer Nummer je Zeile) gäbe und
jeweils alleine in einer Zeile stünde, ginge das Ermitteln der Werte etwa so:
Wenn der Index erst aufgebaut werden muss, indem die Kundennummern aus allen Dateien herausgesucht werden, wäre es tatsächlich sinnvoll, eine Mehrfachverarbeitung zu verhindern - abhängig von zB der verwendeten Backupsoftware könnte dazu das Archiv-Flag verwendet werden:
Um die Ausgabe in eine HTML-Datei zu schreiben, könntest Du den gesamten Code, der vor der zu füllenden Tabelle benötigt wird, als "HTML1.txt" und alles danach als "HTML2.txt" vorbereiten und anstatt
die Zeile
verwenden, die Ausgabe der einzelnen Kunden mit den entsprechenden Tags versehen (Achtung, "<" und ">" müssen als "^<" bzw "^>" maskiert ausgegeben werden) und als letzte Zeile noch
hinzufügen.
Grüße
bastla
P.S.: Alles, was da oben steht, sind übrigens unbewiesene Behauptungen (= ungetestet) ...
[Edit] Suche präziser gestaltet [/Edit]
Soferne es bereits einen Index aller Kundennummern (als Textdatei "KundenNr.txt" mit jeweils einer Nummer je Zeile) gäbe und
<accountnummer>%Kundennummer%</accountnummer>
@echo off & setlocal
set "Ein=D:\XML-Ordner"
set "Aus=D:\Auswertung.txt"
set "Index=D:\KundenNr.txt"
set "Such=\<accountnummer\>"
set "Such2=\</accountnummer\>"
del "%Aus%" 2>nul
pushd "%Ein%"
for /f "usebackq delims=" %%i in ("%Index%") do for /f %%a in ('findstr /m /c:"%Such%%%i%Such2%" *.xml^|find /i /c "xml"') do >>"%Aus%" echo %%i %%a
popd
@echo off & setlocal
set "Ein=D:\XML-Ordner"
set "Aus=D:\Auswertung.txt"
set "Index=D:\KundenNr.txt"
set "Such=\<accountnummer\>"
set "Such2=\</accountnummer\>"
pushd "%Ein%"
if not exist "%Index%" copy nul "%Index%">nul
for /f "delims=" %%i in ('dir /b /aa *.xml') do for /f "tokens=2 delims=<>" %%a in ('findstr /c:"%Such%" "%%i"') do findstr /x "%%a" "%Index%">nul || >>"%Index%" echo %%a
attrib -a *.xml
del "%Aus%" 2>nul
for /f "usebackq delims=" %%i in ("%Index%") do for /f %%a in ('findstr /m /c:"%Such%%%i%Such2%" *.xml^|find /i /c "xml"') do >>"%Aus%" echo %%i %%a
popd
del "%Aus%" 2>nul
copy HTML1.txt "%Aus%">nul
>>"%Aus%" type HTML2.txt
Grüße
bastla
P.S.: Alles, was da oben steht, sind übrigens unbewiesene Behauptungen (= ungetestet) ...
[Edit] Suche präziser gestaltet [/Edit]
Hallo BBuser!
entspricht; die Zerlegung erfolgt ja anhand der Trennzeichen "<" und ">", sodass sich also für diese Zeile die "tokens"
ergeben - befindet sich zB am Beginn der Zeile zumindest ein Leerzeichen (oder zumindest ein anderes Zeichen als "<" oder ">"), verschiebt sich die Nummerierung. Soferne es nur um Leerzeichen ginge, ließe sich die Liste der Trennzeichen ("delims") in Zeile 12 einfach erweitern:
Grüße
bastla
Alles in einer Reihe ist erstmal ok
... und kann auch nicht anders sein, solange in Zeile 16 (lässt sich übrigens leichter referenzieren, wenn Du Deinen Code unter entsprechenden postest) nur "echo %%i %%a
" steht.Aber das Accountref schreibt das Script komischer Weise in die KundenNr.txt
Da der Begriff als "Suchbegriff" verwendet wird, muss er aus einer Zeile stammen, in welcher er das 2. "token" darstellt und die daher nicht der angenommenenen Struktur, zB<accountref>5095</accountref>
1: accountref2: 50953: /accountref
ergeben - befindet sich zB am Beginn der Zeile zumindest ein Leerzeichen (oder zumindest ein anderes Zeichen als "<" oder ">"), verschiebt sich die Nummerierung. Soferne es nur um Leerzeichen ginge, ließe sich die Liste der Trennzeichen ("delims") in Zeile 12 einfach erweitern:
for /f "delims=" %%i in ('dir /b /aa *.xml') do for /f "tokens=2 delims=<> " %%a in ...
bastla
Hallo BBUser!
Deine zusätzlichen Überlegungen kann ich nicht so ganz nachvollziehen - die HTML-Tabellen-Zeilen kannst Du doch problemlos (und mit der Gewissheit, dass KundenNr. und Häufigkeit auch wirklich zusammengehören) etwa so schreiben:
Grüße
bastla
nur der Code aus HTML1.txt landet irgendwie nicht mehr in der Ausgabedatei.
Ist so nicht ganz richtig: bis zur Zeile 15 ist er drin - die hätte eigentlich durch die jetzige Zeile 9 ersetzt werden sollen (was sich ja aber noch immer machen lässt) ...Deine zusätzlichen Überlegungen kann ich nicht so ganz nachvollziehen - die HTML-Tabellen-Zeilen kannst Du doch problemlos (und mit der Gewissheit, dass KundenNr. und Häufigkeit auch wirklich zusammengehören) etwa so schreiben:
... echo ^<tr^>^<td^>%%i^</td^>^<td^>%%a^</td^</tr^>
bastla
Hallo BBUser!
Grüße
bastla
Kann man das noch abstellen?
Ohne Veränderung der Ausgangsdatei (die Begründung für das Auftauchen des Strings findest Du oben) wäre es am einfachsten, im Nachhinein alle Zeilen, in denen "accountref" vorkommt, auszufiltern:move "%Aus%" "%temp%\TempFile.html"
findstr /v "accountref" "%temp%\TempFile.html">"%Aus%"
bastla
Hallo BBUser!
Wieder ungetestet etwa so:
wobei die"Kundenliste.txt" nach dem Schema
aufgebaut ist - das Trennzeichen (%Del% - siehe Zeile 9) soll natürlich so gewählt sein, dass es in keinem Kundennamen vorkommt. Die "KundenRohdaten.txt" wird erst beim nächsten Durchlauf gelöscht und steht daher nach Ende des Batches zur Verfügung, um die Einzelwerte nachvollziehen zu können.
In der Annahme, dass die Kundennamen die Sonderzeichen "<|>" nicht enthalten, wird nur für die korrekte Ausgabe eines "&" vorgesorgt (siehe Zeile 38) ...
Grüße
bastla
P.S.: Mehrere KundenNr für einen einzelnen Kunden finde ich suboptimal ...
[Edit] Gruppenverarbeitung geändert [/Edit]
[Edit2] Zeile 18 (siehe unten) korrigiert [/Edit2]
Dafür müsste man wahrscheinlich eine komplizierte extra Routine verwenden, oder?
Jein - zusammen mit der Frage 2 würde es sich anbieten, eine zusätzliche Kundendatei ("Kundenliste.txt") aufzubauen, welche KundenNr und Kundenname enthält - dann könnte in einem ersten Schritt eine Zwischendatei ("KundenRohdaten.txt") erstellt werden, in welcher die Häufigkeiten je Kunden noch für jede KundenNr getrennt erfasst sind. Nach Sortierung dieser Datei nach dem Kundennamen ließe sich per Gruppenverarbeitung die Summe je Kunden bilden und damit dann die HTML-Datei erstellen - Voraussetzung wäre dafür natürlich, dass die neue Kundendatei sämtliche vorkommenden KundenNr enthält.Wieder ungetestet etwa so:
@echo off & setlocal
set "Ein=F:\XMLtest\XML-Ordner"
set "Aus=F:\XMLtest\XML-OrdnerAuswertung.html"
set "Index=F:\XMLtest\KundenNr.txt"
set "Liste=F:\XMLtest\KundenListe.txt"
set "Roh=F:\XMLtest\KundenRohdaten.txt"
set "Such= <accountref>"
set "Such2=</accountref>"
set "Del=;"
del "%Roh%" 2>nul
pushd "%Ein%"
if not exist "%Index%" copy nul "%Index%">nul
for /f "delims=" %%i in ('dir /b /aa *.xml') do for /f "tokens=2 delims=<>" %%a in ('findstr /c:"%Such%" "%%i"') do findstr /x "%%a" "%Index%">nul || >>"%Index%" echo %%a
attrib -a *.xml
for /f "usebackq delims=" %%i in ("%Index%") do (
for /f "tokens=1* delims=%Del%" %%j in ('findstr /b "%%i%Del%" "%Liste%"') do (
for /f %%a in ('findstr /m /c:"%Such%%%i%Such2%" *.xml^|find /i /c "xml"') do >>"%Roh%" echo "%%k"%Del%%%a
)
)
popd
move "%Roh%" "%temp%\Roh.txt"
sort /o "%Roh%" "%temp%\Roh.txt"
copy HTML1.txt "%Aus%">nul
set "Kunde="
for /f "usebackq tokens=1-2 delims=%Del%" %%k in ("%Roh%") do call :ProcessLine %%k %%l
>>"%Aus%" echo ^<tr^>^<td^>%Kunde:.=%^</td^>^<td^>%Anz%^</td^</tr^>
>>"%Aus%" type HTML2.txt
pause
goto :eof
:ProcessLine
if not defined Kunde goto :Next
if "%Kunde%"==%1 (set /a Anz+=%2 & goto :eof)
>>"%Aus%" echo ^<tr^>^<td^>%Kunde:&=^&%^</td^>^<td^>%Anz%^</td^</tr^>
:Next
set "Kunde=%~1"
set /a Anz=%2
goto :eof
5095;Kundenbeispiel1
5099;Kundenbeispiel2 & so
....;.....
In der Annahme, dass die Kundennamen die Sonderzeichen "<|>" nicht enthalten, wird nur für die korrekte Ausgabe eines "&" vorgesorgt (siehe Zeile 38) ...
Grüße
bastla
P.S.: Mehrere KundenNr für einen einzelnen Kunden finde ich suboptimal ...
[Edit] Gruppenverarbeitung geändert [/Edit]
[Edit2] Zeile 18 (siehe unten) korrigiert [/Edit2]
Hallo BBUser!
"File not found" kann auch daraus resultieren, dass es keine ".xml"-Dateien mit gesetztem "Archiv"-Attribut gibt ...
Zum Debuggen könntest Du alle Ausgaben (also auch die Fehlermeldungen) in eine Textdatei umleiten - wenn der Batch zB "Statistik.cmd" heißt, dann mit
starten - so kannst Du in aller Ruhe den Ablauf nachvollziehen (und falls Du einen vernünfitgen Editor - bei mir wäre das zB Notepad++) verwendest, lassen sich auch per "Suchen / Ersetzen" von "2 Zeilenschaltungen durch 1 Zeilenschaltung" (in "Notepad++" mit "Suchmodus: Erweitert" die Ersetzung von "\r\n\r\n" durch "\r\n") die Leerzeilen eliminieren ...
Grüße
bastla
Brauchen wir die KND.txt eigentlich noch, weil wir haben ja nun die Kundenliste?
Die beiden Dateien haben unterschiedliche Aufgaben: in der "KND.txt" werden alle KundenNr aus den vorhandenen Dateien (ohne Duplikate) gesammelt (Anmerkung: wenn ".xml"-Dateien gelöscht werden, muss die "KND.txt" neu erstellt und daher ebenfalls gelöscht werden), während die "Kundenliste.txt" alle möglichen Kundennummen und die zugehörigen Namen enthält - daher: ja."File not found" kann auch daraus resultieren, dass es keine ".xml"-Dateien mit gesetztem "Archiv"-Attribut gibt ...
Ab der 17. Zeile bricht das Script ab und das Fenster geht zu. Kann man das irgendwie besser debuggen?
Wenn es keine (bzw genauer: nur eine leere) "KND.txt" gibt, hat die Schleife nicht viel zu tun ...Zum Debuggen könntest Du alle Ausgaben (also auch die Fehlermeldungen) in eine Textdatei umleiten - wenn der Batch zB "Statistik.cmd" heißt, dann mit
Statistik >Log.txt 2>&1
Grüße
bastla