Batch doppel var in for Schleife?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

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

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
Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

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

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
Erzesel  15.07.2020, 11:49

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

0
Raptor7000 
Fragesteller
 16.07.2020, 20:07

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.

0