Windows 如何使用于删除旧文件的批处理脚本正常工作?
在文件夹(比如c:\test)中,如果文件数超过21,我想删除最旧的文件 这就是我想到的,问题是它一次删除最旧的文件,第二次运行它什么也不做,第三次删除最旧的文件,继续这样。此外,它不关心文件量是否低于21,即使文件量低于21,也会删除 代码如下:Windows 如何使用于删除旧文件的批处理脚本正常工作?,windows,file,batch-file,scripting,Windows,File,Batch File,Scripting,在文件夹(比如c:\test)中,如果文件数超过21,我想删除最旧的文件 这就是我想到的,问题是它一次删除最旧的文件,第二次运行它什么也不做,第三次删除最旧的文件,继续这样。此外,它不关心文件量是否低于21,即使文件量低于21,也会删除 代码如下: SET BACKUPDIR=C:\test SET countfiles=dir BACKUPDIR /b | find /v /c "::" if countfiles GTR 21 ( FOR /F %%i IN ('DIR /B /O-D %
SET BACKUPDIR=C:\test
SET countfiles=dir BACKUPDIR /b | find /v /c "::"
if countfiles GTR 21 (
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\%OLDEST%
)
这有很多问题
SET countfiles=dir BACKUPDIR /b | find /v /c "::"
在这里,您试图列出名为“BACKUPDIR”的目录中的文件,而不是使用环境变量。应该是
SET countfiles=dir %BACKUPDIR% /b | find /v /c "::"
SET countfiles=dir %BACKUPDIR% /b | find /v /c "::"
不可能工作。这只是分配字符串“dir BACKUPDIR/b | find/v/c”:
“
到环境变量countfiles
。它不会运行任何东西,cmd
如何知道这是要执行的命令
您需要的是以下内容:
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
SET BACKUPDIR=C:\test
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
if %countfiles% GTR 21 (
FOR /F "delims=" %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
这将把countfiles
环境变量的内容设置为上述命令的输出。你可以在中找到更多关于这方面的信息if countfiles GTR 21
这将比较字符串“countfiles”
和字符串“21”
。由于countfiles
在21
之后排序,因此该条件始终为真
您想在此处使用环境变量%countfiles%
:
if %countfiles% GTR 21
cmd
在解析命令时会立即展开环境变量,因此会导致问题。请注意,像上面这样的块被算作cmd
的单个命令。整个块将在运行前被解析,并且在运行时已经替换了其中的所有变量,因此这不是处理该块中可能发生更改的变量的正确方法
这里的解决方案是延迟扩展。可以在批处理开始时包含以下行:
setlocal enabledelayedexpansion
您使用的不是像%OLDEST%
这样的变量!老大代码>。代码>也展开变量,但直接在执行之前展开,而不是在解析时展开。因此,您的代码片段将变成:
if %countfiles% GTR 21 (
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
for/f
循环无法按预期工作。您可以这样修改它:
for /f "delims=" %%i in ...
这确保了行不会在空格处断开(您只会得到第一个标记,直到文件名中的第一个空格,而不是完整的文件名)for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
SET BACKUPDIR=C:\test
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
if %countfiles% GTR 21 (
FOR /F "delims=" %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
我还没有测试过它的每一个方面(床上通话),但我相信它比以前工作得更好,我希望你理解上面的修复以及为什么它们是必要的
顺便说一句:find/v/c:“
是一个漂亮的小把戏。我不知道也没想到
以防万一:如果你真的想继续删除最旧的文件,直到你的文件数降到21以下,那么那一个
If
就不会删除它。你需要建立一个循环,或者继续迭代并重新计算每次迭代的次数,或者只是计算你必须删除的文件数。不过,我将把它作为一个练习。(提示:循环可以通过标签和条件goto
s或使用for/l
来完成。不过,后一个循环需要更多的延迟扩展,因此要小心。)这方面存在许多问题
SET countfiles=dir BACKUPDIR /b | find /v /c "::"
在这里,您试图列出名为“BACKUPDIR”的目录中的文件,而不是使用环境变量
SET countfiles=dir %BACKUPDIR% /b | find /v /c "::"
SET countfiles=dir %BACKUPDIR% /b | find /v /c "::"
不可能工作。这只是分配字符串“dir BACKUPDIR/b | find/v/c”:
“
到环境变量countfiles
。它不会运行任何东西cmd
如何知道这是要执行的命令
您需要的是以下内容:
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
SET BACKUPDIR=C:\test
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
if %countfiles% GTR 21 (
FOR /F "delims=" %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
这将把countfiles
环境变量的内容设置为上述命令的输出。您可以使用找到更多关于这方面的信息if countfiles GTR 21
这将比较字符串“countfiles”
和字符串“21”
。由于countfiles
在21
之后排序,因此此条件始终为真
您想在此处使用环境变量%countfiles%
:
if %countfiles% GTR 21
cmd
在解析命令时会立即扩展环境变量,这会导致问题。请注意,上面这样的块被视为cmd
的单个命令。整个块在运行前会被解析,并且在运行时已替换了其中的所有变量,因此这不是处理变量的正确方法可能在该区块内发生变化的数据
这里的解决方案是延迟扩展。您可以在批处理开始时包括以下行:
setlocal enabledelayedexpansion
您使用的不是像%OLDEST%
这样的变量,而是!OLDEST!
。!
也会展开变量,但在执行前直接展开变量,而不是在解析时展开变量。因此,您的代码段将变成:
if %countfiles% GTR 21 (
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
for/f
循环无法按预期工作。您可以这样修改它:
for /f "delims=" %%i in ...
这确保了行不会在空格处断开(您只会得到第一个标记,直到文件名中的第一个空格,而不是完整的文件名)for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
SET BACKUPDIR=C:\test
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
if %countfiles% GTR 21 (
FOR /F "delims=" %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\!OLDEST!
)
我还没有测试过它的每一个方面(床上通话),但我相信它比以前和现在工作得更好