【问题标题】:batch file remove all but the newest 10 files批处理文件删除除最新的 10 个文件之外的所有文件
【发布时间】:2015-03-03 11:58:01
【问题描述】:

我在批处理文件中有以下内容:

:REMOLDFILES
ECHO Removing files older than 14 days. >>%LOGFILE%
cd /d %BKUPDIR%
FOR /f "skip=14 delims=" %%A IN ('DIR /a:-d /b /o:-d /t:c %1*.zip ^2^>nul') DO IF EXIST "%%~fA" ECHO "%%~fA" >>%LOGFILE%
FOR /f "skip=14 delims=" %%A IN ('DIR /a:-d /b /o:-d /t:c %1*.zip ^2^>nul') DO IF EXIST "%%~fA" DEL "%%~fA" >>%LOGFILE%
FOR /f "skip=14 delims=" %%A IN ('DIR /a:-d /b /o:-d /t:c %1*.log ^2^>nul') DO IF EXIST "%%~fA" ECHO "%%~fA" >>%LOGFILE%
FOR /f "skip=14 delims=" %%A IN ('DIR /a:-d /b /o:-d /t:c %1*.log ^2^>nul') DO IF EXIST "%%~fA" DEL "%%~fA" >>%LOGFILE%
IF [%3]==[Y] GOTO SECONDBACKUPDIR
IF [%3]==[y] GOTO SECONDBACKUPDIR
GOTO END

我遇到的问题是备份已经有几个星期没有运行了,最后删除了我所有的备份,因为它们已经超过 2 周了。

我需要它保留最近 10 个最新备份。

有人知道我会怎么做吗?由于我对批处理文件不太熟悉,所以我没有写过一次。

【问题讨论】:

  • 此代码应删除除最近的 14 *.log*.zip 文件之外的所有文件。将其减少到 10 无济于事。如何确定备份是否已运行?
  • @Magoo - 我也注意到了(我的原始答案因此有 14 天),但 OP 专门要求 10 天。我想他有他的理由(也许周末不运行?)。
  • 您使用的是什么操作系统?您也许可以使用forfiles 命令,它可以轻松解决您的问题。

标签: windows batch-file command-line cmd


【解决方案1】:

您可以使用FOR /F SKIP 在按最后修改日期排序后忽略最近修改的最后 10 个条目:

for /f "skip=10 eol=: delims=" %%F in ('dir /b /o-d *.zip') do @del "%%F"

【讨论】:

  • 完美运行! tyvm!
  • 错了!错误的!错误的!此代码将与原始发布的代码完全相同除了它将删除除最后一个 10 zip 文件之外的所有 zip 文件,而原始允许 14保留。否则,它实际上精确地与原始代码的效果相同,只是它只处理*.zip 文件并且不满足存在名为`*.zip* 的目录的可能性很小现在。
  • @Magoo - “我需要它保留最近 10 个最新备份。”
  • 原始代码保留最后一个 14,抱怨它“最终删除了我所有的备份,因为它们已经超过 2 周了”。原文中的 14 不是 天数,而是文件计数。如果原始代码因为“几个星期没有运行备份”而删除了所需的数据,那么需要设计一些其他方法来确定备份已经运行,因为 存在 .zip 或 .log 显然 not 表明备份已运行。
  • 很棒的单线。非常感谢,您为我节省了很多时间!
【解决方案2】:

您可以使用DIR 命令获取按修改日期倒序排列的文件列表。然后,您只需告诉您的 FOR 循环跳过前 10 个(注意您的邮政编码显示 14,但您要求 10 个)条目,因此处理的任何内容都会被删除。

REM Update to 14 if needed.
SET Keep=10
FOR /F "usebackq tokens=* skip=%Keep% delims=" %%A IN (`DIR *.zip /B /O:-D /A:-D`) DO DEL "%%A">>%LOGFILE%

由于您不熟悉批处理,您可以通过将DEL 替换为ECHO 来测试此命令(查看将删除的内容而不是实际删除的内容)。


编辑

既然你也在处理日志文件,为什么不在同一个循环中删除它们呢?

REM Update to 14 if needed.
SET Keep=10
FOR /F "usebackq tokens=* skip=%Keep% delims=" %%A IN (`DIR *.zip /B /O:-D /A:-D`) DO (
    ECHO Processing: %%~nA
    REM Delete ZIP file.
    DEL "%%A"
    REM Delete LOG file.
    DEL "%%~nA.log"
)>>%LOGFILE%

【讨论】:

  • 与接受的响应相同的问题。您已经省略了/a-d 以排除*.zip 目录(很少见,但理论上可能发生。)避免不必要的重复。本质上,与 OP 的代码相同,但 10 天代替了 14 天 - 而且您的代码不会生成日志文件条目...
  • @Magoo - 如果传递一个目录,DEL 命令将失败,但无论如何最好排除它。关于重定向到日志,你是对的 - 我完全错过了。
  • True - 但如果没有/a-d 目录名行,它将占用免于删除的插槽之一,因此目录将保持不变(del 将失败)但9 , 而不是 10 files 如果前 10 行中的一行是目录而不是文件,则将保留。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
相关资源
最近更新 更多