shorty-xs
Goto Top

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:
[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
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

Content-ID: 73361

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

Ausgedruckt am: 22.11.2024 um 03:11 Uhr

bastla
bastla 16.11.2007 um 22:57:58 Uhr
Goto Top
Hallo shorty-xs und ein verspätetes Willkommen im Forum!

Für die Verarbeitung per Batch wäre eine "artnr.txt" in der Form
Modem#1234#3456#0815#
vorzuziehen, da mit "findstr" dann nur die eine passende Zeile gefunden werden müsste - etwa so:
@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
Die "echo"-Zeile simuliert den Start des "Modem"-Tests.

Grüße
bastla
shorty-xs
shorty-xs 19.11.2007 um 08:42:12 Uhr
Goto Top
Hallo Bastla, vielen Dank!
Ich glaube das kann ich schon fast benutzen. Hab da aber noch ein paar Fragen, bzw. Änderungen.
Hallo shorty-xs und ein verspätetes
Willkommen im Forum!
Danke!

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:
Modem#1234#3456#0815#
OK, das geht. Kann ich dann Artikelnummern für andere Komponeneten dort auch unterbringen? z.B. so:
Modem#1234#3456#0815#
GSM#4356#9854#
COM3-4#2543#0981#
 

Das muß ich erstmal auseinander nehmen damit ich's verstehe:
@echo off & setlocal
::set "SNr=D:\serinummer.txt" 
set "SNr=.\%_sn%.txt"  
set "ANr=D:\artnr.txt"  
Soweit klar, echo ist schon vorher aus, setlocal begrenzt die Variablen auf diesen Bereich. Ich hab schon eine globale Variable %_sn%, ich glaube die kann ich dafür auch benutzen. Die ArtNr. txt würde ich glaube ich auch global anlegen, damit ich mehrfach drauf zugreifen kann. Ansonsten etwa so:
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?
 
:ProcessNumber
set Typ=
for /f "delims=#" %%a in ('findstr "#%~1#" "%ANr%"') do set "Typ=%%a"  
if not defined Typ goto :eof
Hier wird die Artikelnummern Zeile immer um ein feld verschoben. Damit nach Art.Nr jeder einmal gesucht wird. Ist glaube ich klar soweit.
Der Test start würde bei mir warschienlich so aussehen:
Die "echo"-Zeile
simuliert den Start des
"Modem"-Tests.

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 ?
Grüße
bastla
Gruß, Malte
bastla
bastla 19.11.2007 um 12:35:33 Uhr
Goto Top
Hallo Malte!

Kann ich dann Artikelnummern für andere Komponeneten dort auch unterbringen? z.B. so:
Modem#1234#3456#0815#
GSM#4356#9854#
COM3-4#2543#0981#
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.

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?
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).

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 ?
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
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"  
...
...
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
if "%Typ%"=="Modem" call "D:\Batch\Modemtest.cmd"  
if "%Typ%"=="GSM" call "D:\Batch\GSMtest.cmd"  
...
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
shorty-xs
shorty-xs 19.11.2007 um 13:05:18 Uhr
Goto Top
Erstmal vielen Dank Bastla!
Ich muß erstmal damit rumspielen. Mein Ziel ist zwar etwas anders, es könnte ja auch vor kommen, dass Modem und GSM drin sind, aber Du hast mir schonmal gewaltig weiter geholfen.

Ich würde also für jede Komponente die ich testen will nach dem vorhanden sein in der Stückliste suchen und dann testen, oder eben nicht.

Werde meine Ergebnisse natürlich hier posten!

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?
bastla
bastla 19.11.2007 um 15:22:28 Uhr
Goto Top
Hallo Malte!

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 Art
set /p "Ger=Welchen Geraetetyp testen?"  
voschalten. Danach kannst Du dann über
if /i "%Ger%"=="%Typ%" call "D:\Batch\%Typ%test.cmd"  
gezielt den gewünschten Test aufrufen. Alternative, um mehrere Geräte angeben zu können:
echo %Ger%|findstr /i "%Typ%" >nul && call "D:\Batch\%Typ%test.cmd"  
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
shorty-xs
shorty-xs 19.11.2007 um 16:09:03 Uhr
Goto Top
Noch mals vielen Dank für Deine Hilfe,
ich hatte heute leider erst noch ein anderes Problem zu lösen, und konnte Dein Beispiel nicht testen. Ich vergesse manchmal, dass ich in Gedanken schon etwas weiter bin wie hier im forum face-wink Ich versuch es mal ohne Batch, einfach nur mit Text zu beschreiben.

Es geht darum das in einem Rechner verschiedenen Optionen vorhanden sein können.
Das kann Modem sein, das können aber auch 2 zusätzliche Serielle schnittstellen (COM3-4) sein oder eine W-LAN Karte, oder oder oder. Alles nur Beispiele-

Was drin ist, steht als Artikelnummern in der Stückliste. Diese wurde bisher nur für die unbeaufsichtigte Installation benutzt.

Wir haben ein Testscript, welches die benötigten Tests abruft. Im Moment muß der Tester dann selber auswählen ob die jeweilige Komponenten im Rechner ist oder nicht. Dies möchte ich um Zeit und Fehler zu sparen, gerne automatisieren.

Wenn also jetzt das Testscript an dem Punkt ankommt, an dem das Modem (falls vorhanden) getestet werden soll. Starte ich die Suche nach den möglichen Artikelnummern für das Modem. Wenn kein Modem drin ist, schreibe ich das so in's Protokoll.
An dem Punkt an dem wenn vorhanden COM3-4 getstet werden sollen, suche ich nach diesen möglichen Artiklenummern, um zu entscheiden Test JA/NEIN. usw.
bastla
bastla 20.11.2007 um 00:03:12 Uhr
Goto Top
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
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
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
shorty-xs
shorty-xs 20.11.2007 um 08:09:59 Uhr
Goto Top
Wow, das isses.
Werde aber wohl heute auch noch nicht viel weiter kommen.

Melde mich so bald es was neues gibt.

Nochmals besten Dank.

Greetz
Malte