130834
Goto Top

Variablen Zusammenbauen 2.0 ( Batch )

Hey Leute.

Ich bin's mit dieser wunderschönen Fortsetzung des "Großen Variablen Problems"

Damals ging es darum in einem goto Loop eine Variable aus einem Counter und einem Namen zusammenzubauen.

Funktioniert soweit gut, wenn ich das mit !VariableX%counter%! praktiziere.
Leider bin ich über goto loops hinaus, da diese das Skript verlangsamen.
Ich habe ein neues Skript, welches mit einem FOR Loop Linien aus einer TXT ausliest, und diese in Line1 usw abspeichert.
Line1 usw wird so gesetzt:
for /f "usebackq delims=" %%i in ("%userprofile%\Desktop\Eine.txt") do ( set /a lines+=1  & set "line!lines!=%%i" )  

Ich wollte dann das Skript noch etwas verfeinern, in dem es mir die Buchstaben in der Line zählt und
diese in eine Neben-Variable sowas wie Line1le einspeichert.
Um zu sehen ob das ganze Funktioniert hab ich dann einen DEBUG echo gemacht.
Dieser zeigt mir, das das ganze ganz und gar nicht funktioniert.
Ich kann weder !Line!lines!! noch !Line!Lines!le! ausgeben. War auch klar.
Nur wie umgehe ich das jetzt?
Ich kann die !lines! Variable nicht mehr mit %Prozentzeichen% zusammen benutzen, da ich mich nun in einem FOR Loop befinde.
Aus irgendeinem Grund hat bei mir
set "cline=line!lines!  
echo !cline!
nicht funktioniert.

hier ein Beispiel des Codes

@echo off
setlocal enableextensions enabledelayedexpansion
for /f "usebackq delims=" %%i in ("%userprofile%\Desktop\Eine.txt") do (  
set /a lines+=1 
set "line!lines!=%%i"   
set "cline=line!lines!  
call :length "%%i" "line!lines!le"  
echo [DEBUG] Line!lines! has now the value !cline! and the length !line!lines!le!
)
echo pre phase completed. script stopped
pause>nul
exit

:length <measure> <output>
set "string=%~1"  
:lengthsub
if defined string ( set "string=%string:~1%" & set /a "len +=1" & goto lengthsub )  
set /a "%~2=%len%"  
exit /b

Um ihn auszuprobieren müsste man eine Eine.txt Textdatei auf dem Desktop erstellen und einfach ein paar Dinge hinenschreiben z.b

Salat
Brot
Käse
Fisch
Eier
Kartoffeln

Das script solle dann eigentlich für jede Linie die Länge und den Inhalt hinter dem [DEBUG] anzeigen.

Freue mich auf HIlfe,

schönen Abend, clragon

Content-Key: 320985

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

Ausgedruckt am: 19.03.2024 um 03:03 Uhr

Mitglied: rubberman
rubberman 14.11.2016 um 21:14:47 Uhr
Goto Top
Hallo clragon.

Am einfachsten geht das, indem du die Variable lines in einer FOR /F Schleife verarbeitest. Die FOR Variable kannst du dann wieder in einer Variablenverschachtelung verwenden.
@echo off
setlocal enableextensions enabledelayedexpansion
for /f "usebackq delims=" %%i in ("%userprofile%\Desktop\Eine.txt") do (  
  set /a lines+=1 
  set "line!lines!=%%i"   
  set "cline=line!lines!  
  call :length "%%i" "line!lines!le"  
  for /f %%j in ("!lines!") do echo [DEBUG] Line%%j has now the value !cline! and the length !line%%jle!  
)
echo pre phase completed. script stopped
pause>nul
exit

:length <measure> <output>
set "len=0"  
set "string=%~1"  
:lengthsub
if defined string ( set "string=%string:~1%" & set /a "len +=1" & goto lengthsub )  
set /a "%~2=%len%"  
exit /b
(Hab len für jeden Aufruf auf 0 zurückgesetzt ...)

Grüße
rubberman
Mitglied: 130834
130834 14.11.2016 um 21:53:15 Uhr
Goto Top
Hey! Danke für die Hilfe.

Zwar funktioniert damit das Längen-Messen echt gut, jedoch wird der Inhalt der Variable trotzdem nicht angezeigt,
Bzw er wird angezeigt, nur ist das nicht der Inhalt den ich haben will.
Hier ein Bild:

Man sieht darauf, das !cline! nur die aktuelle Linie angibt, jedoch nicht den Inhalt der Linie, wie gedacht.

Vieleicht hast du ja auch dafür eine Idee.

LG clragon
screenshot_1
Mitglied: rubberman
Lösung rubberman 14.11.2016 um 22:12:26 Uhr
Goto Top
Ach so, hab ich übersehen. Aber das Prinzip ist dasselbe.
@echo off
setlocal enableextensions enabledelayedexpansion
for /f "usebackq delims=" %%i in ("%userprofile%\Desktop\Eine.txt") do (  
  set /a lines+=1 
  set "line!lines!=%%i"   
  call :length "%%i" "line!lines!le"  
  for /f %%j in ("!lines!") do (set "cline=!line%%j!" &set clength=!line%%jle!)  
  echo [DEBUG] Line!lines! has now the value !cline! and the length !clength!
)
echo pre phase completed. script stopped
pause>nul
exit

:length <measure> <output>
set "len=0"  
set "string=%~1"  
:lengthsub
if defined string ( set "string=%string:~1%" & set /a "len +=1" & goto lengthsub )  
set /a "%~2=%len%"  
exit /b
Wenn es sich irgendwie vermeiden lässt, solltest du natürlich die Erstellung solcher assoziativer Arrays weglassen und gleich mit der FOR Variablen arbeiten...
Mitglied: Biber
Biber 15.11.2016 aktualisiert um 10:44:46 Uhr
Goto Top
Moin clragon,

ohne an rubbermans Lösung reumzumäkeln . ich würde eine andere Strategie wählen.
Das Simulieren von Array-Strukturen/verschachtelten Variablen verursacht relativ einzigartige Probleme bei der CMD-Batch.


Weil.... hey! Wenn ich beim Durchlaufen eines Arrays nicht mal in einem Arbeitsschritt/einem Schleifendurchlauf sowohl Werte setzen kann wie auch diese auslesen.. wie soll ich so arbeiten?

(BTW: Das sind allerdings Probleme, deren Lösung auch kein Nobelpreiskomitee honorieren wird.)

In der Tendenz würde ich mich den Gegebenheiten anpassen - wenn es nicht in EINEM Arbeitsschritt möglich ist, dann machen wir das halt in zweien.

@echo off
setlocal enableextensions enabledelayedexpansion

REM Eine For-Anweisung zum Ermitteln der Werte ubnd Speichern in Variablen
for /f "usebackq delims=" %%i in (".\Eine.txt") do (  
  set /a lines+=1 
  set "line!lines!=%%i"   
  call :length "%%i" "line!lines!len"  
)
REM Eine For-Anweisung zum Ausgeben der gesetzten Variablen
FOR /L %%i in (1,1,%lines%) do (
echo [DEBUG] Line%%i has now the value [!Line%%i!] and the length line%%ilen=!line%%ilen!
)
echo pre phase completed. script stopped

pause>nul
goto :eof 
: exit

:length <measure> <output>
set "string=%~1"  
set len=0
:lengthsub
if defined string ( set "string=%string:~1%" & set /a "len +=1" & goto lengthsub )  
set /a "%~2=%len%">nul  
goto :eof
: exit /b

Ausgabe:
[DEBUG] Line1 has now the value [Salat bleifrei] and the length line1len=14
[DEBUG] Line2 has now the value [Brot mit Pommes] and the length line2len=15
[DEBUG] Line3 has now the value [Thunfischmarmelade] and the length line3len=18
[DEBUG] Line4 has now the value [Fischlebkuchen] and the length line4len=14
[DEBUG] Line5 has now the value [Eier mit Honig] and the length line5len=14
[DEBUG] Line6 has now the value [Kartoffeln] and the length line6len=10
pre phase completed. script stopped

Wenig Verrenkungen beim Setzen der Variablen in der ersten FOR-Anweisung, wenig Stress beim Auslesen in der zweiten FOR-Anweisung.

Grüße
Biber
Mitglied: 130834
130834 15.11.2016 um 21:08:40 Uhr
Goto Top
Heya! Danke für die Lösung.

Ich finde zwar, das meine Probleme durchaus mit einem Nobelpreis honoriert werden sollten,
und außerdem hast du Käse vergessen, aber das Script oben hat auf Jedenfalls die gewünschte Wirkung gezeigt,
nämlich die längste Linie zu finden und das war es ja auch was ich wollte.

Der Rest funktioniert jetzt auch sehr gut, und ich kann mich endlich darauf fokussieren, Die ToDo's auf der Liste
auch ABZUARBEITEN anstatt nur eine Liste dafür zu programmieren...

schönen Abend,
clragon
Mitglied: Biber
Biber 16.11.2016 um 12:08:47 Uhr
Goto Top
Moin clragon,

und außerdem hast du Käse vergessen,
Aber dafür gab es lecker Fischlebkuchen und Thunfischmarmelade extra für dich.

Man sollte auch offen für Neues sein. face-wink

Grüße
Biber