79728
Goto Top

Eine Art while Funktion in Batches

Kann ich statt "goto" Funktion auch eine "for" schleife nehmen?

Aufgabe lautete: Falls das letzte Zeichen einer Variable ein "\" ist, soll es entfernt werden.

Eine Lösungsmöglichkeit siehe Batch1

Frage: Kann ich die "goto schleifen" auch vereinfachen und mit mittels einer for schleife eine art "while" funktion basteln?
z.B. siehe Batch2, dort ergibt es zwar nicht wirklich sinn aber es fuktioniert in so fern, dass die letzten 3 "\" entfernt werden... Also scheint die Schleife zumindest 3x durchzulaufen...


BATCH1:
@echo off & setlocal enabledelayedexpansion

set Datenquelle=\\tsclient\C\VOL1\\\\\\\\\
set Datenziel=C:\VOL1\\\\

:check
if "!Datenquelle:~-1!"=="\" (set Datenquelle=!Datenquelle:~0,-1!) else (  
if "!Datenziel:~-1!"=="\" (set Datenziel=!Datenziel:~0,-1!) else (goto weiter)  
)
goto check

:weiter
echo Datenquelle = %Datenquelle%
echo Datenziel = %Datenziel%
pause


BATCH2:
@echo off & setlocal enabledelayedexpansion

set Datenquelle=\\tsclient\C\VOL1\\\\\\\\\\\
set Datenziel=C:\VOL1\\\

for %%d in (if "%Datenquelle:~-1%"=="\") do (  
if "!Datenquelle:~-1!"=="\" (set Datenquelle=!Datenquelle:~0,-1!)  
if "!Datenziel:~-1!"=="\" (set Datenziel=!Datenziel:~0,-1!)  
)

echo Datenquelle = %Datenquelle%
echo Datenziel = %Datenziel%
pause

Mir ist klar, dass in besagtem Beispiel eine Variable kaum mehr als 1 "\" am Ende haben wird. Stelle die Frage nur interessehalber...
Danke für Ideenvorschläge!

Content-Key: 178886

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

Printed on: April 16, 2024 at 12:04 o'clock

Member: rubberman
rubberman Jan 13, 2012 at 14:55:12 (UTC)
Goto Top
Hallo 123456,
Lösung könnte sein:
@echo off &setlocal

set "Datenquelle=\\tsclient\C\VOL1\\\\\\\\\\\"  
set "Datenziel=C:\VOL1\\\"  

set "RTrim=\"  

setlocal EnableDelayedExpansion

for /l %%i in (1 1 12) do set "RTrim=!RTrim!!RTrim!"  

set /a "k = 4096"  
for /l %%j in (1 1 13) do (
  if defined Datenquelle for %%k in (!k!) do (
    if "!Datenquelle:~-%%k!"=="!RTrim:~-%%k!" set "Datenquelle=!Datenquelle:~0,-%%k!"  
    set /a "k /= 2"  
  )
)

set /a "k = 4096"  
for /l %%j in (1 1 13) do (
  if defined Datenziel for %%k in (!k!) do (
    if "!Datenziel:~-%%k!"=="!RTrim:~-%%k!" set "Datenziel=!Datenziel:~0,-%%k!"  
    set /a "k /= 2"  
  )
)

echo Datenquelle = !Datenquelle!
echo Datenziel = !Datenziel!

pause

Auch ohne Gruß...
Member: bastla
bastla Jan 13, 2012 at 18:14:26 (UTC)
Goto Top
Ich habe diese Frage als "anspruchsvoll" bewertet, da sie die Zusatzaufgabe enthält, vor der Lösung erst einmal das Problem zu finden ... face-wink

Ansonsten zB (mit Schleife):
for /f "delims=" %%i in ("%Datenquelle%") do set "Datenquelle=%%~fi"  
if "%Datenquelle:~-1%"=="\" set "Datenquelle=%Datenquelle:~,-1%"  
bastla
Member: Biber
Biber Jan 13, 2012 at 19:42:15 (UTC)
Goto Top
Na, dann sag ich auch mal was an der Frage vorbei.... face-wink

Das (Bei-)Spielproblem würde ich ähnlich wie bastla abfackeln:
d:\temp>set "Datenquelle=\\tsclient\C\VOL1\\\\\\\\\\\\\\\\\\\\\\"

d:\temp>for %i in ("%datenquelle%\bla\..") do @echo ohne trailing backslashes: [%~fi]
ohne trailing backslashes: [\\tsclient\C\VOL1]

Die eigentliche Frage nach der while-ähnlichen Batchkonstruktion: Nein.
Nicht das ich Anhänger von GOTOs wäre....
... aber selbst diese Krücke ist, wie rubberman aufgezeigt hat, immer noch lesbarer und pflegbarer als etwas Selbstgehäkeltes.mit DelayedExpansion.

Und da die Frage war: "Geht es nicht einfacher?" --> no way.

Biber
Member: rubberman
rubberman Jan 13, 2012 at 20:22:49 (UTC)
Goto Top
Hallo Biber.

Völlig d'accord. So geht's am einfachsten und das Ganze ist alternativlos performant.

Zwei Anmerkungen hätte ich noch:
- mein Beispiel ist ein Right-Trim, der nicht nur auf Backslashes anwendbar wäre
- das strikte Nein zu einer while-ähnlichen Struktur möchte ich nicht so im Raum stehen lassen
@echo off &setlocal

REM :: ruft Subroutine :while auf (nach Selbstaufruf)
if "%~1"==":while" call %~1  

REM :: innerhalb der Schleife wird der Batch in einer neuen CMD-Instanz mit Argument ":while" aufgerufen 
for /f "tokens=1,2" %%i in ('cmd /c "%~f0" :while') do set /a num1=%%i, num2=%%j  

echo num1=%num1%
echo num2=%num2%

pause>nul &goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:while
setlocal EnableDelayedExpansion
set /a num1=0
set /a num2=0

REM :: Endlosschleife
for /l %%# in (0) do (
  REM :: zu lesen wie WHILE !num2! < 1000
  if !num2! lss 1000 (
    set /a "num1 += 1"  
    set /a "num2 += num1"  
  ) else (
    REM :: diese Ausgabe wird in der FOR Schleife verarbeitet
    echo !num1! !num2!
    REM :: das EXIT ist die einzige Möglichkeit die Endlosschleife regulär abzubrechen
    exit
  )
)
Man kann ganz sicher geteilter Meinung sein, ob das so nun sinvoller als per GOTO ist. Für GOTO-Hasser sicherlich face-wink

Grüße
rubberman
Mitglied: 79728
79728 Jan 14, 2012 at 16:20:17 (UTC)
Goto Top
Wow. Ich danke euch allen herzlichst für die Ideen!
Lieben Gruß