Suche nach mehreren Suchbegriffen in einer ASCII Datei, und wenn vorhanden eine Aktion ausführen
Hallo Ihrs,
ich hab ja schon viele wirklich gute Infos hier aus dem Forum gelesen, (Danke dafür) zu diesem Problem hab ich aber noch nichts gefunden.
Problem:
Ich habe eine ASCII Datei in der Artikelnummern in verschiedenen Reihenfolgen auftauchen, immer gefolgt von einer Zeile die die Anzahl dieser Komponente im Rechner. Ich möchte jetzt nach bestimmten Artiklenummern suchen um einen Test zu starten, wenn diese Artiklenummer vorhanden ist.
Beispiel ich suche ein Modem, das kann aber die ArtNr 1234 oder 3456 oder 0815 haben. Wenn ich eine dieser Artiklenummern finde, muß ich den Modemtest starten.
Mein Ansatz währe der, dass ich die möglichen Artiklenummer in einer Textdatei zusammen fasse, jede Nr. in einer eigenen Zeile, und oben drüber eine Sektion also:
Nenne wir sie mal artnr.txt
Dann kann ich alle Artikelmummern in einer Datei sammeln, weil das soll später für andere Komponenten auch noch kommen.
Jetzt möchte ich in der Stücklisten datei (serinummer.txt) die etwa so aussieht:
möchte ich nun durchsuchen. Es könnte auch sein, dass die Artikelnummer merhmals vorhanden ist, dann muß ich 2 mal testen.
Das müsste ja mit einer verschachtelten for schleife gehen, aber mit welchen Parameter, ich hab ja schon einiges an Erfahrung mit batch aber die for paramter blicke ich immer noch nicht.
Ich habe schon folgende Artikel gelesen:
Wort innerhalb einer Textdatei finden und Zeile auslesen mit Batch-Datei
Such-Assistent starten und diesem Parameter übergeben
Mittels Batch-Datei einen Installationspfad herausfinden
Gruß
Malte
ich hab ja schon viele wirklich gute Infos hier aus dem Forum gelesen, (Danke dafür) zu diesem Problem hab ich aber noch nichts gefunden.
Problem:
Ich habe eine ASCII Datei in der Artikelnummern in verschiedenen Reihenfolgen auftauchen, immer gefolgt von einer Zeile die die Anzahl dieser Komponente im Rechner. Ich möchte jetzt nach bestimmten Artiklenummern suchen um einen Test zu starten, wenn diese Artiklenummer vorhanden ist.
Beispiel ich suche ein Modem, das kann aber die ArtNr 1234 oder 3456 oder 0815 haben. Wenn ich eine dieser Artiklenummern finde, muß ich den Modemtest starten.
Mein Ansatz währe der, dass ich die möglichen Artiklenummer in einer Textdatei zusammen fasse, jede Nr. in einer eigenen Zeile, und oben drüber eine Sektion also:
[Modem]
1234
3456
0815
Nenne wir sie mal artnr.txt
Dann kann ich alle Artikelmummern in einer Datei sammeln, weil das soll später für andere Komponenten auch noch kommen.
Jetzt möchte ich in der Stücklisten datei (serinummer.txt) die etwa so aussieht:
5643
#1
0977
#1
5123
#2
1234
#1
Das müsste ja mit einer verschachtelten for schleife gehen, aber mit welchen Parameter, ich hab ja schon einiges an Erfahrung mit batch aber die for paramter blicke ich immer noch nicht.
Ich habe schon folgende Artikel gelesen:
Wort innerhalb einer Textdatei finden und Zeile auslesen mit Batch-Datei
Such-Assistent starten und diesem Parameter übergeben
Mittels Batch-Datei einen Installationspfad herausfinden
Gruß
Malte
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 73361
Url: https://administrator.de/contentid/73361
Ausgedruckt am: 22.11.2024 um 03:11 Uhr
8 Kommentare
Neuester Kommentar
Hallo shorty-xs und ein verspätetes Willkommen im Forum!
Für die Verarbeitung per Batch wäre eine "artnr.txt" in der Form
vorzuziehen, da mit "findstr" dann nur die eine passende Zeile gefunden werden müsste - etwa so:
Die "echo"-Zeile simuliert den Start des "Modem"-Tests.
Grüße
bastla
Für die Verarbeitung per Batch wäre eine "artnr.txt" in der Form
Modem#1234#3456#0815#
@echo off & setlocal
set "SNr=D:\serinummer.txt"
set "ANr=D:\artnr.txt"
for /f "delims=" %%i in ('findstr /v "#" "%SNr%"') do call :ProcessNumber "%%i"
goto :eof
:ProcessNumber
set Typ=
for /f "delims=#" %%a in ('findstr "#%~1#" "%ANr%"') do set "Typ=%%a"
if not defined Typ goto :eof
echo Starte den %Typ%-Test fuer %~1
Grüße
bastla
Hallo Malte!
Da ja nur die Nummern, aber nicht die Mengen, aus der Seriennummerndatei interessieren, filtere ich alle Zeilen, welche ein "#" enthalten, vorweg aus (noch genauer wäre ein zusätzliches "/b").
Mit "goto :eof" sorge ich dafür, dass nach dem Abarbeiten der gesamten Seriennummerndatei aber auch mal Schluss ist (und der Batch nicht nochmals in das ":ProcessNumber"-Unterprogramm läuft).
Das "if not defined" prüft, ob (in der bereits ergänzten "ArtNr.txt") überhaupt ein Gerät gefunden wurde (da %Typ% ansonsten gar nicht existiert). Insofern wäre vor das "goto :eof" besser noch die Ausgabe einer entsprechenden Fehlermeldung zu setzen, etwa
Die Fortsetzung würde ich dann vielleicht so gestalten:
In zB D:\Batch (natürlich auch besser per Variable angegeben) liegen dann eben die "Modemtest.cmd", "GSMtest.cmd", ... Damit sparst Du Dir die Abfragen der Art
und könntest zusätzlich per Else auch noch einfach auf den Fall reagieren, dass zwar der Gerätetyp festgestellt werden konnte, aber die Testprogrammdatei dazu nicht vorhanden wäre.
Grüße
bastla
Kann ich dann Artikelnummern für andere Komponeneten dort auch unterbringen? z.B. so:
Das war eigentlich der Plan - "findstr" findet die Zeile mit der Artikelnummer, und mit "for" hole ich mir das erste Token (der hoffentlich einzigen, falls aber nicht, der letzten entsprechenden) Zeile.Modem#1234#3456#0815#
GSM#4356#9854#
COM3-4#2543#0981#
GSM#4356#9854#
COM3-4#2543#0981#
for /f "delims=" %%i in ('findstr /v "#" ".\%_sn%.txt"') do call :ProcessNumber "%%i"
goto :eof
Für was steht die Raute in der findstr Klammer? Wozu das goto :eof?goto :eof
Mit "goto :eof" sorge ich dafür, dass nach dem Abarbeiten der gesamten Seriennummerndatei aber auch mal Schluss ist (und der Batch nicht nochmals in das ":ProcessNumber"-Unterprogramm läuft).
if "%Typ%"=="Modem" (
echo Starte den %Typ%-Test fuer %~1
call :Modemtest )
if not defined Typ echo Kein Modem Installiert >>log.txt
Ich bin nicht so der Held mit Klammern, die if not defined Zeile im Testablauf kann man doch bestimmt durch ein else ersetzen, wo muß das hin? Mit in die Klammer ?echo Starte den %Typ%-Test fuer %~1
call :Modemtest )
if not defined Typ echo Kein Modem Installiert >>log.txt
if not defined Typ echo Artikelnummer %~1 in der Datei ArtNr.txt nicht gefunden. >>log.txt & goto :eof
Die Fortsetzung würde ich dann vielleicht so gestalten:
if exist "D:\Batch\%Typ%test.cmd" call "D:\Batch\%Typ%test.cmd"
...
...
if "%Typ%"=="Modem" call "D:\Batch\Modemtest.cmd"
if "%Typ%"=="GSM" call "D:\Batch\GSMtest.cmd"
...
Grüße
bastla
Hallo Malte!
voschalten. Danach kannst Du dann über
gezielt den gewünschten Test aufrufen. Alternative, um mehrere Geräte angeben zu können:
wobei in %Ger% zB "Modem#COM3-4#COM7-8" eingegeben wurde.
Voraussetzung in beiden Fällen: Die Eingabe muss (bis auf die Groß-/Kleinschreibung) der Schreibweise in der "ArtNr.txt" entsprechen.
Grüße
bastla
P.S. mir fällt gerade ein, kann man das nicht anders rum aufziehen? Ich suche erstmal nach Modem in der ArtNr.txt und vergleiche dann die dahinter stehenden Nummern ob diese in der Stückliste %_sn%.txt sind?
Solange ich nicht genauer weiß, was Du überhaupt vorhast, kann ich nicht beurteilen, was vorteilhafter wäre - wenn Du nicht für alle Geräte Tests durchführen willst, kannst Du ja einfach nur nach den zu testenden Geräten suchen und zu diesem Zweck eine Eingabe der Artset /p "Ger=Welchen Geraetetyp testen?"
if /i "%Ger%"=="%Typ%" call "D:\Batch\%Typ%test.cmd"
echo %Ger%|findstr /i "%Typ%" >nul && call "D:\Batch\%Typ%test.cmd"
Voraussetzung in beiden Fällen: Die Eingabe muss (bis auf die Groß-/Kleinschreibung) der Schreibweise in der "ArtNr.txt" entsprechen.
Grüße
bastla
Hallo Malte!
Dann wird es tatsächlich sinnvoller sein, die Suche umzukehren - trotzdem würde ich bei der zeilenorientierten Struktur (wie oben dargestellt) der ArtNr.txt bleiben, allerdings nur Gerätetyp und Artikelnummern durch zB "=" (kann aber natürlich auch "#" bleiben) trennen und zwischen die Artikelnummern jeweils Leerstellen setzen, also
Der (ungetestete) "Test-Start-Batch" könnte dann so aussehen:
Noch einige Hinweise zum Ablauf:
Die Verwendung des allgemeinen Unterprogrammes ":Check" (mit Übergabe des Gerätetyps als Parameter) setzt voraus, dass jedes Testprogramm von einem Batch mit dem Namen "%Typ%test.cmd" aufgerufen wird - es muss also "Modemtest.cmd", "GSMtest.cmd", "COM3-4test.cmd", etc geben. Wird ein entsprechender Batch nicht gefunden, erfolgt ein Eintrag im Protokoll "log.txt". Dem Testbatch wird (falls dort zB zu Dokuzwecken benötigt) die Artikelnummer des gefundenen Gerätes als Parameter %1 übergeben.
In der ersten "for"-Schleife wird jene Zeile, die mit dem Gerätetyp beginnt, in der Datei "ArtNr.txt" (dafür wurde, analog zur Variablen "%_sn%", "%_an%.txt" verwendet) gesucht und in die beiden Teile "Typbezeichnung" (%%i) und "Artikelnummern" (%%j) zerlegt. Wird keine entsprechende Zeile gefunden, so wird die Variable "ArtGer" nicht gesetzt, was am Ende des Unterprogramms zu einem entsprechenden Eintrag in die "log.txt" führt.
Die nächste Schleife geht alle Artikelnummern durch (ohne "/f", da die einzelnen Nummern ohnehin durch Leerstellen getrennt sind und daher einzeln erfasst werden können) und sucht jede einzelne Nummer (nur am Beginn jeder Zeile) in der Seriennummerndatei. Für jeden gefundenen Eintrag wird das Testprogramm aufgerufen - damit wäre sogar der Fall abgedeckt, dass die selbe Artikelnummer mehrmals in der Seriennummerndatei vorkäme.
Sobald auch nur eine Artikelnummer des überprüften Typs gefunden wurde, wird der Schalter "Ger" gesetzt - somit kann nach Durchlauf aller zum jeweiligen Typ gehörigen Artikelnummern anhand des Zustandes von "Ger" (vorhanden = "defined": Gerät gefunden; nicht vorhanden = "not defined": Gerät nicht gefunden) protokolliert werden, falls kein Artikel des zu testenden Gerätes in der Seriennummerndatei aufzufinden war.
Dass übrigens auch die "log.txt" über eine Variable angesprochen sowie am Beginn des Batches gelöscht werden sollte, sei nur erwähnt, ist aber noch nicht berücksichtigt.
Grüße
bastla
Dann wird es tatsächlich sinnvoller sein, die Suche umzukehren - trotzdem würde ich bei der zeilenorientierten Struktur (wie oben dargestellt) der ArtNr.txt bleiben, allerdings nur Gerätetyp und Artikelnummern durch zB "=" (kann aber natürlich auch "#" bleiben) trennen und zwischen die Artikelnummern jeweils Leerstellen setzen, also
Modem=1234 3456 0815
GSM=4356 9854
COM3-4=2543 0981
Der (ungetestete) "Test-Start-Batch" könnte dann so aussehen:
@echo off & setlocal
set "TestDir=D:\Batch"
echo Modem-Test
call :Check "Modem"
...
...
...
echo GSM-Test
call :Check "GSM"
...
...
echo Fertig.
goto :eof
:Check
set Ger=
set ArtGer=
for /f "tokens=1* delims==" %%i in ('findstr /b /i "%~1" "%_an%.txt"') do (
set ArtGer=True
for %%n in (%%j) do (
for /f "delims=" %%a in ('findstr /b "%%n" "%_sn%.txt"') do (
set Ger=True
if exist "%TestDir%\%%itest.cmd" (call "%TestDir%\%%itest.cmd %%n") else echo %%itest.cmd nicht gefunden >>log.txt
)
)
)
if not defined ArtGer echo %%i nicht in %_an%.txt gefunden >>log.txt & goto :eof
if not defined Ger echo Kein %%i installiert >>log.txt
goto :eof
Die Verwendung des allgemeinen Unterprogrammes ":Check" (mit Übergabe des Gerätetyps als Parameter) setzt voraus, dass jedes Testprogramm von einem Batch mit dem Namen "%Typ%test.cmd" aufgerufen wird - es muss also "Modemtest.cmd", "GSMtest.cmd", "COM3-4test.cmd", etc geben. Wird ein entsprechender Batch nicht gefunden, erfolgt ein Eintrag im Protokoll "log.txt". Dem Testbatch wird (falls dort zB zu Dokuzwecken benötigt) die Artikelnummer des gefundenen Gerätes als Parameter %1 übergeben.
In der ersten "for"-Schleife wird jene Zeile, die mit dem Gerätetyp beginnt, in der Datei "ArtNr.txt" (dafür wurde, analog zur Variablen "%_sn%", "%_an%.txt" verwendet) gesucht und in die beiden Teile "Typbezeichnung" (%%i) und "Artikelnummern" (%%j) zerlegt. Wird keine entsprechende Zeile gefunden, so wird die Variable "ArtGer" nicht gesetzt, was am Ende des Unterprogramms zu einem entsprechenden Eintrag in die "log.txt" führt.
Die nächste Schleife geht alle Artikelnummern durch (ohne "/f", da die einzelnen Nummern ohnehin durch Leerstellen getrennt sind und daher einzeln erfasst werden können) und sucht jede einzelne Nummer (nur am Beginn jeder Zeile) in der Seriennummerndatei. Für jeden gefundenen Eintrag wird das Testprogramm aufgerufen - damit wäre sogar der Fall abgedeckt, dass die selbe Artikelnummer mehrmals in der Seriennummerndatei vorkäme.
Sobald auch nur eine Artikelnummer des überprüften Typs gefunden wurde, wird der Schalter "Ger" gesetzt - somit kann nach Durchlauf aller zum jeweiligen Typ gehörigen Artikelnummern anhand des Zustandes von "Ger" (vorhanden = "defined": Gerät gefunden; nicht vorhanden = "not defined": Gerät nicht gefunden) protokolliert werden, falls kein Artikel des zu testenden Gerätes in der Seriennummerndatei aufzufinden war.
Dass übrigens auch die "log.txt" über eine Variable angesprochen sowie am Beginn des Batches gelöscht werden sollte, sei nur erwähnt, ist aber noch nicht berücksichtigt.
Grüße
bastla