Подтвердить что ты не робот

Пока цикл в партии

Вот что я хочу, внутри BACKUPDIR, я хочу выполнить cscript /nologo c:\deletefile.vbs %BACKUPDIR%, пока количество файлов внутри папки больше 21 (countfiles удерживает его). Вот мой код:

@echo off
SET BACKUPDIR=C:\test
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x

for %countfiles% GTR 21 (
cscript /nologo c:\deletefile.vbs %BACKUPDIR%
set /a countfiles-=%countfiles%
)
4b9b3361

Ответ 1

set /a countfiles-=%countfiles%

Это установит countfiles в 0. Я думаю, вы хотите уменьшить его на 1, поэтому используйте это вместо:

set /a countfiles-=1

Я не уверен, будет ли цикл for работать, лучше попробуйте что-то вроде этого:

:loop
cscript /nologo c:\deletefile.vbs %BACKUPDIR%
set /a countfiles-=1
if %countfiles% GTR 21 goto loop

Ответ 2

В while цикл может быть смоделирован в cmd.exe с:

:still_more_files
    if %countfiles% leq 21 (
        rem change countfile here
        goto :still_more_files
    )

Например, следующий скрипт:

    @echo off
    setlocal enableextensions enabledelayedexpansion
    set /a "x = 0"

:more_to_process
    if %x% leq 5 (
        echo %x%
        set /a "x = x + 1"
        goto :more_to_process
    )

    endlocal

выходы:

0
1
2
3
4
5

Для вашего конкретного случая я бы начал со следующего. Ваше первоначальное описание было немного запутанным. Я предполагаю, что вы хотите удалить файлы в этом каталоге до 20 или менее:

    @echo off
    set backupdir=c:\test

:more_files_to_process
    for /f %%x in ('dir %backupdir% /b ^| find /v /c "::"') do set num=%%x
    if %num% gtr 20 (
        cscript /nologo c:\deletefile.vbs %backupdir%
        goto :more_files_to_process
    )

Ответ 3

@echo off

set countfiles=10

:loop

set /a countfiles -= 1

echo hi

if %countfiles% GTR 0 goto loop

pause

на первом "set countfiles" 10, которое вы видите, это количество, которое будет зацикливаться echo hi - это то, что вы хотите зацикливать

... я опаздываю на 5 лет

Ответ 4

У меня есть хитрость для этого!

Я придумал этот метод, потому что в то время как в CLI было невозможно использовать методы, представленные в других ответах здесь, и это всегда меня беспокоило.

 Я называю это циклом "До перерыва" или "Бесконечный":

Основной пример

FOR /L %L IN (0,0,1) DO @(
 ECHO. Counter always 0, See "%L" = "0" - Waiting a split second&ping -n 1 127.0.0.1>NUL )

Это действительно бесконечный цикл!

Это полезно для мониторинга чего-либо в окне CMD и позволяет вам использовать CTRL + C, чтобы разбить его, когда вы закончите.

Хотите иметь счетчик?

Либо используйте SET /A, либо вы можете изменить цикл FOR /L, чтобы выполнять подсчет, и при этом оставаться бесконечным (обратите внимание, ОБА из этих методов имеют 32-битное целочисленное переполнение)

SET /A Метод:

FOR /L %L IN (0,0,1) DO @(
 SET /A "#+=1"&ECHO. L Still equals 0, See "%L = 0"!  - Waiting a split second &ping -n 1 127.0.0.1>NUL  )

Собственный счетчик FOR /L:

FOR /L %L IN (-2147483648,1,2147483648) DO @(
 ECHO.Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL  )

Подсчет наборов 4294967295 и отображение текущего значения L:

FOR /L %L IN (1,1,2147483648) DO @(
 (
  IF %L EQU 0 SET /A "#+=1">NUL
 )&SET /A "#+=0"&ECHO. Sets of 4294967295 - Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL )

Однако, что если:

  • Вы заинтересованы в просмотре выходных данных монитора и обеспокоены тем, что я преодолею ограничение в 9999 строк буфера, прежде чем проверять его после его завершения.
  • Вы хотели бы предпринять некоторые дополнительные действия после того, как Вещи, за которыми я наблюдаю, будут завершены.

Для этого я определил, как использовать пару методов, чтобы преждевременно разорвать цикл FOR, превратив его в цикл "DO WHILE" или "DO UNTIL", которого в CMD крайне не хватает.

ПРИМЕЧАНИЕ. Большую часть времени цикл будет повторяться после условия, которое вы проверяли, часто это желаемое поведение, но не в нашем случае.

Превратите "бесконечный цикл" в цикл "DO WHILE"/"DO UNTIL"

ОБНОВЛЕНИЕ: В связи с желанием использовать этот код в сценариях CMD (и сделать так, чтобы они сохранялись!), А также в CLI, а также при размышлении о том, существует ли для этого "более правильный" метод, я рекомендую использовать метод New!

Новый метод (может использоваться внутри сценариев CMD без выхода из сценария):

FOR /F %%A IN ('
  CMD /C "FOR /L %%L IN (0,1,2147483648) DO @( ECHO.%%L & IF /I %%L EQU 10 ( exit /b  ) )"
') DO @(
  ECHO %%~A
)

В CLI:

FOR /F %A IN ('
  CMD /C "FOR /L %L IN (0,1,2147483648) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b  ) )"
') DO @(
  ECHO %~A
)

Оригинальный метод (будет отлично работать с CLI, но убьет скрипт.)

FOR /L %L IN (0,1,2147483648) DO @(
  ECHO.Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL&(
    IF /I %L EQU 10 (
      ECHO.Breaking the Loop! Because We have matched the condition!&DIR >&0
    )
  )
) 2>NUL

Старые посты

Случайно я наткнулся на некоторые способы преждевременного выхода из циклов, которые не закрывали подсказку CMD при попытке сделать другие вещи, которые дали мне эту идею.

  Примечание:

Хотя ECHO.>&3 >NUL работал для меня в некоторых сценариях, я играл с этим время от времени и обнаружил, что DIR >&0 >NUL был гораздо более последовательным.

Я переписываю этот ответ здесь, чтобы использовать этот метод вместо этого, поскольку недавно я нашел для себя старую записку об использовании этого метода.

Сообщение отредактировано с лучшим методом следующим образом:

DIR >&0 >NUL

Параметр> NUL является необязательным, я просто предпочитаю, чтобы он не выводил ошибку.

Я предпочитаю сопоставлять inLine, когда это возможно, как вы можете видеть в этом очищенном примере команды, которую я использую для мониторинга миграций LUN на нашем VNX.

for /l %L IN (0,0,1) DO @(
   ECHO.& ECHO.===========================================& (
     [VNX CMD] | FINDSTR /R /C:"Source LU Name" /C:"State:" /C:"Time " || DIR >&0 >NUL
   ) & Ping -n 10 1.1.1.1 -w 1000>NUL )

Кроме того, у меня есть другой метод, который я нашел в этой заметке для себя, который я только что повторно протестировал, чтобы подтвердить, что он работает в CLI так же хорошо, как и другой метод.

Очевидно, когда я впервые разместил здесь сообщение, я опубликовал более старую итерацию, с которой я играл, вместо двух более новых, которые работают лучше:

В этом методе мы используем EXIT /B для выхода из цикла For Loop, но мы не хотим выходить из CLI, поэтому мы переносим его в сеанс CMD:

FOR /F %A IN ('CMD /C "FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b  ) )" ') DO @(ECHO %~A)

Поскольку сам цикл происходит в сеансе CMD, мы можем использовать EXIT/B для выхода из итерации цикла без потери нашего сеанса CMD и без ожидания завершения цикла, почти так же, как и в другом методе.

Я бы сказал, что этот метод, вероятно, является "предназначенным" для сценария, в котором вы хотите разорвать цикл for в CLI, поскольку использование сеанса CMD также является единственным способом заставить работать отложенное расширение на CLI для ваших циклов, а также поведение и такое поведение явно предназначены для выхода из сеанса CMD.

IE: Microsoft явно предприняла преднамеренные усилия для того, чтобы циклы CMD Exit/B For вели себя таким образом, в то время как "намеренный" способ сделать это, как и мой другой метод, основан на том, что случайно создал только правильную ошибку, чтобы выкинуть вас из цикл, не позволяя циклу завершить обработку, которую я только случайно обнаружил, и, кажется, надежно работает только при использовании команды DIR, что довольно странно.

Таким образом, я думаю, что лучше использовать метод 2:

FOR /F %A IN ('CMD /C "FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b  ) )" ') DO @(ECHO %~A)

Хотя я подозреваю, что способ 1 будет немного быстрее:

FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( DIR >&) >NUL ) )

И в любом случае, оба должны разрешать циклы DO-While, как вам нужно для ваших целей.

Ответ 5

Это было очень полезно для меня, я использовал следующий способ добавления пользователя в активный каталог:

:: This file is used to automatically add list of user to activedirectory
:: First ask for username,pwd,dc details and run in loop
:: dsadd user cn=jai,cn=users,dc=mandrac,dc=com -pwd `1q`1q`1q`1q

@echo off
setlocal enableextensions enabledelayedexpansion
set /a "x = 1"
set /p lent="Enter how many Users you want to create : "
set /p Uname="Enter the user name which will be rotated with number ex:ram then ram1 ..etc : "
set /p DcName="Enter the DC name ex:mandrac : "
set /p Paswd="Enter the password you want to give to all the users : "

cls

:while1

if %x% leq %lent% (

    dsadd user cn=%Uname%%x%,cn=users,dc=%DcName%,dc=com -pwd %Paswd%
    echo User %Uname%%x% with DC %DcName% is created
    set /a "x = x + 1"
    goto :while1
)

endlocal

Ответ 6

Это можно сделать с помощью цикла do while ... enddo.