Batch doppel var in for Schleife?
Guten Abend
Komme mit meinem Batch Scribt nicht voran.
Das Problem was ich habe ist einerseits eine doppel Variable und ein set Befehl was die Geschichte in einer for Schleife auch nicht einfacher macht.
Was macht das Scribt?
Das Zeil wäre das es alle Wlannamen raussucht die es jemals verbunden war und sie dann weiterverarbeitet.
SET one=1
set namenumber=7
set immer=1
set name=name
SETLOCAL ENABLEDELAYEDEXPANSION
for /F "tokens=* USEBACKQ" %%F in (`netsh wlan show profiles`) do (
set name!one!=%%F
set /a one=!one!+1
)
:namenumber
if [!%name%%namenumber%!]==[] (
set /A namenumber=%namenumber%-1
) else (
set /a namenumber=%namenumber%+%immer%
goto namenumber
)
for /L %%A in (7,1,%namenumber%) do (
set namenumber=%%A
set test=!name%namenumber%!
set wlan!%namenumber%!=%test:~27%
)
2 Antworten
ich nehme das mal Hoch, da es auch für andere Leute nützlich sein könnte.
Sollte es doch einmal unumgänglich sein statt einer Laufvariable eine echte Variable innerhalb einer Variable zu verwenden, muss man dies außerhalb des Klammerblocks auswerten:
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
for /l %%a in (1,1,10) do (
set /a "__index=%%a+10000"
set "Array.!__index!=laberBlub #%%a#"
rem call initialsiert intern eine neue Istanz von cmd die Verdopplung zu %% maskiert das %, so das der Befehl diesese erst in der Neuen Instanz als Variable auflöst!
rem und schon sind wir außerhalb des Klammerblocks
call echo %%Array.!__index!%%
rem Raute entfernen
call set "Test=%%Array.!__index!:#=%%"
echo !Test!
)
pause
...sollte man jedoch nur machen wenn es sich nicht lohnt oder nicht möglich ist die gesamte Routine auszulagern (jeder call frist Zeit)
...oder das Standardverfahren :
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
for /l %%a in (1,1,10) do (
rem unterprogramm mit Parameter aufrufen
call :irgendeinLabel %%a
)
pause
rem dafür sorgen, das das Hauptprogramm nicht in die subroutinen überläuft
rem hier ist Programmende
exit /b
::::: Subroutines :::::
:irgendeinLabel %1=wert von %%a
rem hier haben wir keinen Klammerblock und können voll auf jede Variable zugreifen
set /a "__index=%1+10000"
set "Array.%__index%=miffmaff #%1#"
echo !Array.%__index%!
set "Test=!Array.%__index%:#=!"
echo %Test%
rem zurük zum Aufrufer
exit /b
- https://ss64.com/nt/call.html
- https://ss64.com/nt/set.html
- https://ss64.com/nt/syntax-functions.html
Das dürfte die schnellste Variante sein, wird aber schnell unübersichtlich und die Anzahl der Laufvariablen ist begrenzt:
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
for /l %%a in (1,1,10) do (
set /a "__index=%%a+10000"
rem machen wir eine Laufvariable aus der normalen Variable
for %%i in (!__index!) do (
set Array.%%i=fuzzlie #%%a#
echo !Array.%%i!
set "Test=!Array.%%i:#=!"
echo !Test!
)
)
set array.
pause
mann kann auch mehrere Variablen in einem Rutsch in Laufvariablen exportieren:
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
for /l %%a in (1,1,10) do (
set /a "__index=%%a+10000"
set /a "__index2=%%a+200"
set /a "__index3=%%a+666"
for /f "tokens=1-3 delims=," %%i in ("!__index!,!__index2!,!__index3!") do (
echo %%i %%j %%k
rem wie gehabt nur das wir jetzt 3 Laufvariablen erzeugt haben
)
)
pause
Die allerbeste Variante ist , es garnicht erst zu einer Situation kommen zu lasse das Obiges nötig wird.
Ich habe mal das erste Script abgespeckt, da es nur um die Spielerei mit Variablen und Arrays geht
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
@(
echo Laberhababer ....
echo:
echo --------------------
echo Laberhababer ....
echo --------------------
echo Profil für alle Benutzer : Tarnkatze
echo Profil für alle Benutzer : Ratte
echo Profil für alle Benutzer : Kampfmops
echo Profil für alle Benutzer : Eselhimmel
)>"profile.txt"
set "namenumber=0"
for /f "tokens=1* delims=:" %%a in ('type "profile.txt"^|find "Profil"') do (
set /a "namenumber+=1"
set "__SSID=%%b" &set "__SSID=!__SSID:~1!"
rem ein . als feldtrenner zwischen Variablename und Indexnummer... wirst später sehen warum
set "name.!namenumber!=!__SSID!"
)
rem mal die Variablen welche mit Name beginnen anzeigen
set "name"
rem da wir bereits mit find "Profil" die relevanten Zeilen selektiert haben ist es unmöglich eien leere Variable/Zeile zu haben oder irgend etwas anwas wir nicht benötigen!
rem auch das trennen der Zeile hat sich erldigt, denn das hat "tokens=1* delims=:" recht effizient erledigt
rem der rest ist trivial:
echo:
echo Schleife 1:
for /l %%a in (1,1,%namenumber%) do (
rem mache irgendwas mit dem pseudoArray name.index
echo Name Nummer: %%a = !name.%%a!
)
echo:
echo schleife2
rem die Namennummer müssen wir garnicht haben! Die steht ja bereits im Variablennamen!
rem set "VariableName" gibt Variablenname...=Wert aus (und zwar für alle)
rem jetzt zeige ich dir wozu der Punkt (oder ein anderer Trenner) gut ist:
rem wir bauen ein ForEach (für Jedes) -Konstrukt anderer Programiersprachen nach! (die obige Namenumber ist garnicht meher nötig)
rem Input in Token 1 2 und Rest an '.' und '=' trennen...
for /f "tokens=1,2* delims=.=" %%a in ('set "name."') do (
rem mal Anzeigen, wie das aufgedröselt aussieht
echo Name=%%a Index=%%b Wert=%%c
rem in ein anderes Array kopieren
set "Wlan.%%b=!name.%%b!
)
set wlan
pause
Ich habe an meinem Rechner leider kein WLan, deshalb muss ich etwas zaubern.
Auf Informationen bezüglich der Ausgabe von "netsh wlan..." (aus dem Internet), erzeuge ich deshalb eine Simulation, um Dir zu zeigen wie es ohne die Zahlenorgie funktioniert. (du musst die Ausgabe nur nach einzigartigen Schlagworten für das was Du brachst filtern --- find WortteilDerZeile)
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
rem schreibe SimulationsDateien ---abgespeckt vom Befehl "netsh wlan show profile" ...usw
@(
echo LaberRhababer
echo:
echo Konnektivitätseinstellungen
echo -------------------------
echo Anzahl von SSIDs : 1
echo SSID-Name : "TarnKatze"
echo Netzwerktyp : Infrasfrastruktur
echo LaberRhababer
echo Sicherheitseinstellungen
echo --------------------
echo Authentifiziehrung : WPA2-Personal
echo Laber : Irgendwas
echo Schlüsselinhalt : SuperGehmeispasswort
echo LaberRhababer
echo:
)>"Tarnkatze.txt"
@(
echo LaberRhababer
echo:
echo Konnektivitätseinstellungen
echo -------------------------
echo Anzahl von SSIDs : 1
echo SSID-Name : "Ratte"
echo Netzwerktyp : Infrasfrastruktur
echo LaberRhababer
echo Sicherheitseinstellungen
echo --------------------
echo Authentifiziehrung : WPA2-Personal
echo Laber : Irgendwas
echo Schlüsselinhalt : anderesPasswort127564
echo LaberRhababer
echo:
)>"Ratte.txt"
@(
echo Laberhababer ....
echo --------------------
echo Laberhababer ....
echo --------------------
echo Profil für alle Benutzer : Tarnkatze
echo Profil für alle Benutzer : Ratte
)>"profile.txt"
rem speichern wir doch alle Ergebnisse in einer kleinen Datenbank (CSV)
rem Heater schreiben
echo "SSID";"Encryption";"Password">"Database.csv"
for /f "tokens=1,* delims=:" %%a in ('type "profile.txt"^|find "Profil"') do (
rem entferne das führende Leerzeichen im Namen (einfach erstes Zeichen abschneiden)
set "__SSID=%%b" &set "__SSID=!__SSID:~1!"
for /f "tokens=1,* delims=: " %%c in ('type "!__SSID!.txt"') do (
rem jetzt kommt der Trick, wenn mehere Sachen abgefragt werden sollen filtern wir erst innerhalb der der Schleife
rem &&... nur ausführen wenn Errorlevel 0 also gefunden
rem Ausgabe nach spezifischen Strings durchsuchen und nur bei Treffer verarbeiten:
echo %%c|find "Auth" >nul && (set "__KeyTyp=%%d" &set "name=!__KeyTyp~1!")
echo %%c|find "inhalt" >nul && (set "__Passwort=%%d" &set "name=!__Passwort~1!")
)
rem speichern wir doch alle Ergebnisse in einer kleinen Datenbank (CSV)
echo "!__SSID!";"!__KeyTyp!";"!__Passwort!" >>"Database.csv"
)
echo:
echo Datenbank anzeigen...
type "Database.csv"
pause
...davon abgeleitet sollte auch das funktionieren (ungetestet):
@echo off
for /f "tokens=1,* delims=:" %%a in ('netsh wlan show profiles^|find "Profil"') do (
set "__SSID=%%b" &set "__SSID=!__SSID:~1!"
for /f "tokens=1,* delims=: " %%c in ('netsh wlan show profile name^="!__SSID!" key^=clear') do (
echo %%c|find "Auth" >nul && (set "__KeyTyp=%%d" &set "name=!__KeyTyp~1!")
echo %%c|find "inhalt" >nul && (set "__Passwort=%%d" &set "name=!__Passwort~1!")
)
echo "!__SSID!";"!__KeyTyp!";"!__Passwort!" >>"Database.csv"
)
echo:
echo Datenbank anzeigen...
type "Database.csv"
pause
...wie man ein CSV in Batch auswertet :
for /f "usebackq tokens=1-3 delims=;" %%a in ("Database.csv") do (
echo SSID=%%~a
echo SchluesselTyp=%%~b
echo Passwort=%%c
echo:
)
...natürlich kannst Du ein csv auch nach Exel (..oder ander Tabellenprogramme importieren...
Vielen Dank für deine rasche Antwort.
Deine Idee mit dem direkten suchen ist sehr hilfreich. Die werde ich auf jeden Fall dann in mein Programm einbinden. Nur leider hast du meine Frage nicht ganz beantwortet. Ich wollte eigentlich nur wissen, wie ich das in der for Schleife fixen kann. Deine Lösung ist zwar auch super aber nicht für mich geeignet da ich nicht möchte, dass die Batch mit Datenbanken oder txt arbeitet.
upps:
kleiner Fix für die innere Schleife:
Leerzeichen hinter dem Doppelpunkt entfernen...
for /f "tokens=1,* delims=:" %%c ......
und diese 2 zeilen ersetzen:
echo %%c|find "Auth" >nul && (set "__KeyTyp=%%d" &set "__KeyTyp=!__KeyTyp:~1!")
echo %%c|find "inhalt" >nul && (set "__Passwort=%%d"&set "__Passwort=!__Passwort:~1!")
Die Oberen Demos laufen zwar auch wie ich es zuvor hatte, aber aber die Abfrage einer Zeile mit Leerzeichen innerhalb des Begriffs vor dem Doppelpunkt würde falsche Ergebnisse liefern...