Hel*_*nar 46 windows for-loop batch-file while-loop
这是我想要的内容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%
)
Run Code Online (Sandbox Code Playgroud)
sch*_*der 54
set /a countfiles-=%countfiles%
Run Code Online (Sandbox Code Playgroud)
这会将countfiles设置为0.我认为你想将它减少1,所以请改用:
set /a countfiles-=1
Run Code Online (Sandbox Code Playgroud)
我不确定for循环是否有效,更好的尝试这样的事情:
:loop
cscript /nologo c:\deletefile.vbs %BACKUPDIR%
set /a countfiles-=1
if %countfiles% GTR 21 goto loop
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 48
一个while循环可以模拟在cmd.exe有:
:still_more_files
if %countfiles% leq 21 (
rem change countfile here
goto :still_more_files
)
Run Code Online (Sandbox Code Playgroud)
例如,以下脚本:
@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
Run Code Online (Sandbox Code Playgroud)
输出:
0
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)
对于您的具体情况,我将从以下开始.你的初步描述有点令人困惑.我假设您要删除该目录中的文件,直到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
)
Run Code Online (Sandbox Code Playgroud)
我想出了这个方法,因为在 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 )
Run Code Online (Sandbox Code Playgroud)
这真的是一个无限循环!
这对于监视CMD窗口中的某些内容很有用,并允许您在完成后使用CTRL+C来中断它。
想要柜台吗?
要么使用SET /AOR 您可以修改FOR /LLoop 来进行计数并且仍然是无限的(注意,这两种方法都有 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 )
Run Code Online (Sandbox Code Playgroud)
本地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 )
Run Code Online (Sandbox Code Playgroud)
计算 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 )
Run Code Online (Sandbox Code Playgroud)
但是,如果:
为此,我确定了如何使用几种方法FOR过早地打破循环,有效地将它变成“ DO WHILE”或“ DO UNTIL”循环,否则 CMD 非常缺乏这种循环。
注意:大多数情况下,循环会继续迭代您检查过的条件,这通常是一种想要的行为,但在我们的情况下不是。
DO WHILE”/“ DO UNTIL”循环更新:由于想在 CMD 脚本(并让它们持久化!)以及 CLI 中使用此代码,并且考虑是否可能有“更正确”的方法来实现这一点,我建议使用新方法!
新方法(无需退出脚本即可在 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
)
Run Code Online (Sandbox Code Playgroud)
在 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
)
Run Code Online (Sandbox Code Playgroud)
原始方法(可以在 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
Run Code Online (Sandbox Code Playgroud)
偶然地,我找到了一些过早退出循环的方法,这些方法在尝试做其他给我这个想法的事情时并没有关闭 CMD 提示。
虽然ECHO.>&3 >NUL在某些情况下对我有用,但多年来我一直在玩这个,发现它DIR >&0 >NUL更加一致。
我正在重新编写此答案以改用该方法,因为我最近发现自己的旧笔记改用此方法。
DIR >&0 >NUL
Run Code Online (Sandbox Code Playgroud)
>NUL 是可选的,我只是不想让它输出错误。
我更喜欢在可能的情况下匹配 inLine,正如您在我用来监控 VNX 上的 LUN 迁移的这个经过清理的命令示例中所见。
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 )
Run Code Online (Sandbox Code Playgroud)
另外,我在给自己的笔记中找到了另一种方法,我刚刚重新测试了该方法以确认在 CLI 中的效果与另一种方法一样好。
显然,当我第一次在这里发布时,我发布了一个我正在玩的旧版本,而不是两个效果更好的新版本:
在该方法中,我们使用EXIT /B退出 For 循环,但我们不想退出 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)
Run Code Online (Sandbox Code Playgroud)
因为循环本身发生在 CMD 会话中,所以我们可以使用 EXIT /B 退出循环的迭代而不会丢失我们的 CMD 会话,并且无需等待循环完成,与其他方法非常相似。
我什至会说这种方法可能是您想要在 CLI 中中断 for 循环的那种场景的“预期”方法,因为使用 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)
Run Code Online (Sandbox Code Playgroud)
虽然我怀疑方法 1 会稍微快一点:
FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( DIR >&) >NUL ) )
Run Code Online (Sandbox Code Playgroud)
在任何一种情况下,两者都应该允许 DO-While 循环,因为您需要满足您的目的。
小智 6
@echo off
set countfiles=10
:loop
set /a countfiles -= 1
echo hi
if %countfiles% GTR 0 goto loop
pause
Run Code Online (Sandbox Code Playgroud)
在第一个“ set countfiles”上,您看到的10是循环的数量echo hi是您要循环的东西
...我迟了5年
| 归档时间: |
|
| 查看次数: |
343843 次 |
| 最近记录: |