Wie kann ich einen Zyklus in einer FOR-Schleife überspringen?

Wie kann ich einen Zyklus in einer FOR-Schleife überspringen?

Ich führe ein Batch-Skript zur Verarbeitung einiger Dateien aus. Wenn festgestellt wird, dass die aktuelle Datei nicht verarbeitet werden muss, möchte ich die restlichen Befehle für diese Datei überspringen und direkt zur nächsten übergehen. Wie? Goto :EOFund exit /bbeide beenden das gesamte Skript.

Hier ist das Skript. Es nimmt ein Verzeichnis und benennt alle Dateien um, sodass alle Wörter aus den Namen der übergeordneten Verzeichnisse enthalten sind, mit Ausnahme der Wörter, die bereits im Dateinamen enthalten sind.

@echo off
setlocal enabledelayedexpansion

rem set input directory (add check for validity)
set "inputDir=%~1"
set "confirmation=false"

:proceed
for /r "%inputDir%" %%F in (*.*) do (
    rem use path to file as keywords
    set "words=%%~pF"
    rem replace known useless marks with spaces
    set "words=!words:\= !"
    set "words=!words:_= !"
    set "words=!words:,= !"
    set "words=!words:  = !"
    rem remove known useless words
    set "words=!words: The = !"
    set "words=!words: A = !"
    set "words=!words: An = !"
    set "words=!words: Video = !"
    set "words=!words: New Folder = !"
    rem remove word that already exists in the filename
    for %%W in (!words!) do echo %%~nF | find /i "%%W" >nul && set "words=!words: %%W = !"
    rem replace leading and trailing spaces with brackets
    set "words=[!words:~1,-1!]"
    rem if all words already included end task for current file
    if "!words!"=="[]" exit /b
    rem build the new filename
    set "newName=%%~nF !words!%%~xF"
    rem fix "] [" caused by repeated renaming, causes fusion with non-related bracketed sets, which is fine
    set "newName=!newName:] [= !"
    rem task for displaying the name change for confirmation
    if /i not "%confirmation%"=="yes" echo old "%%F" && echo new "!newName!"
    rem task for doing the actual rename if confirmed
     if /i "%confirmation%"=="yes" echo ren "%%~nxF" "!newName!" & echo ren "%%F" "!newName!"
)

rem fails to rename files with ! mark in the filename. no other trouble, just won't rename those. error: the syntax of the command is incorrect

rem if coming from second (completed) run then exit
if /i "%confirmation%"=="yes" exit /b
rem ask for confirmation to run again for real
set /p confirmation="confirm you want to perform all these rename tasks (type yes or no)?: "
if /i not "%confirmation%"=="yes" echo confirmation denied
if /i "%confirmation%"=="yes" goto proceed

endlocal

Ich versuche auch eine alternative Methode, die letzten Befehle bedingt auszuführen, wie folgt

@echo off
setlocal enabledelayedexpansion

rem set input directory (add check for validity)
set "inputDir=%~1"
set "confirmation=false"

:proceed
for /r "%inputDir%" %%F in (*.*) do (
    rem use path to file as keywords
    set "words=%%~pF"
    rem replace known useless marks with spaces
    set "words=!words:\= !"
    set "words=!words:_= !"
    set "words=!words:,= !"
    set "words=!words:  = !"
    rem remove known useless words
    set "words=!words: The = !"
    set "words=!words: A = !"
    set "words=!words: An = !"
    set "words=!words: Video = !"
    set "words=!words: New Folder = !"
    rem remove word that already exists in the filename
    for %%W in (!words!) do echo %%~nF | find /i "%%W" >nul && set "words=!words: %%W = !"
    rem replace leading and trailing spaces with brackets
    set "words=[!words:~1,-1!]"
    rem if all words not already included in the filename do
    if not "!words!"=="[]" (
        rem build the new filename
        set "newName=%%~nF !words!%%~xF"
        rem fix "] [" caused by repeated renaming, causes fusion with non-related bracketed sets, which is fine
        set "newName=!newName:] [= !"
        rem task for displaying the name change for confirmation
        if /i not "%confirmation%"=="yes" echo old "%%F" && echo new "!newName!"
        rem task for doing the actual rename if confirmed
        if /i "%confirmation%"=="yes" echo ren "%%~nxF" "!newName!" & echo ren "%%F" "!newName!"
    )
)

rem fails to rename files with ! mark in the filename. no other trouble, just won't rename those. error: the syntax of the command is incorrect

rem if coming from second (completed) run then exit
if /i "%confirmation%"=="yes" exit /b
rem ask for confirmation to run again for real
set /p confirmation="confirm you want to perform all these rename tasks (type yes or no)?: "
if /i not "%confirmation%"=="yes" echo confirmation denied
if /i "%confirmation%"=="yes" goto proceed

endlocal

Dies ist jedoch eine Katastrophe, da die Dateinamen aus scheinbar zufälligen Teilen des Dateinamens zusammengesetzt und wordshinzugefügt werden.

Antwort1

Platzieren Sie einfach ein Label :nextiteration(oder einen beliebigen anderen Namen) als letzte Anweisung im Hauptteil der For-Schleife und gotozu diesem Label, wenn Sie entscheiden, dass Sie den Rest des For-Hauptteils überspringen können.

Da einer schließenden Klammer im FOR-Textkörper eine normale Anweisung vorangestellt werden muss (ein Label reicht nicht aus), müssen Sie zwischen dem Label und der schließenden Klammer eine Dummy-Anweisung (z. B. ein REM) einfügen.

FOR xxxxxxxxx DO (
  some statements (executed on each iteration)
  IF {some condition is met} GOTO nextiteration
  statements that will be skipped if conditon is met
:nextiteration
  REM to prevent syntax error
)

Antwort2

Windows Batch bietet nicht viele Möglichkeiten, eine Iteration der Schleife zu überspringen. Folgende Methoden können Sie verwenden:

  • Setzen Sie einen IF-Block um den Teil der Schleife, den Sie überspringen möchten:

    @Echo Off
    if A equ A (
      IF B==C (
        Echo shouldn't go here
      )
    )
    
  • Verwenden Sie es call, um eine Routine aufzurufen, die die gesamte innere Schleife enthält. Folgendes exit/Bfunktioniert:

     @Echo Off
     Setlocal 
     For %%A in (alpha beta gamma) DO (
       Echo Outer loop %%A
       Call :inner 
     )
     Goto :eof
    
     :inner
     For %%B in (U V W X Y Z) DO (
       if %%B==X ( exit /b 2 )
       Echo    Inner loop    Outer=%%A Inner=%%B
     )
    
  • Verwenden Sie den Befehl goto :Labelund setzen Sie ihn Label: an das Ende der Schleife. Dies wird in Ihrem Fall wahrscheinlich aufgrund eines bekannten Fehlers nicht funktionieren: Die Verwendung von GOTO in Klammern, einschließlich FOR- und IF-Befehlen, führt zu einem Abbruch.
    Ein Beispiel, das den Fehler zeigt:

    @Echo Off
    if A equ A (
      IF B==C GOTO specialcase 
        Echo shouldn't go here
        goto:eof 
    :specialcase
    )
    

Referenz :

Antwort3

Versuchen Sie es mit For /F...und... | findstr /c:"string1" /c:"string2"...

Verwenden Sie eine Schleife, die Ihnen das Filtern der Zeichenfolgen ermöglicht und Ihnen somit mehr Kontrolle über die Aktionen mit den resultierenden Interrese-Dateinamen gibt. Dies erleichtert Ihnen die Interaktion zum Umbenennen, ohne dass Sie versuchen müssen, die Schleife zu überspringen, da sie präziser wird:

@echo off & setlocal

2>nul cd /d "%~1" || exit 

setlocal enabledelayedexpansion

for %%G in =;( 
     "_",",","  "," The "," A "," An "," Video "," New Folder " 
    );= do if not defined _str2find =;( set "_str2find=/c:"%%~G""
        );= else call set "_str2find=!_str2find! /c:"%%~G""

setlocal disabledelayedexpansion

for /f usebackq^delims^= %%G in (`
    2^>nul where /r . *.* ^| findstr %_str2find% `);= do =;( 
      echo/%%~G 
      :: So you don't need to use skip, the rest of your 
      :: interactions continue here and within your loop 
     );=

endlocal 

verwandte Informationen