如何在具有多个文件夹组的文件夹中删除一组文件夹中最旧的文件夹? [英] How to remove oldest folder(s) of a group of folders in a folder with several folder groups?

查看:98
本文介绍了如何在具有多个文件夹组的文件夹中删除一组文件夹中最旧的文件夹?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文件夹D:\Backup包含以下子文件夹,在其中列出了名称(左)和上次修改日期(右),如Windows资源管理器中所示:

The folder D:\Backup contains following subfolders listed here with name (left) and last modification date (right) as displayed in Windows Explorer:

20171113.224424         15.11.2017 17:24
20171113.224421         16.11.2017 15:26
20171113.224412         16.11.2017 15:33
20171112.424424         16.11.2017 15:33
20171112.224424         16.11.2017 15:33
20171112.221424         16.11.2017 15:34
20171111.224428         16.11.2017 15:34
20171111.224427         16.11.2017 15:35
20171111.224424         16.11.2017 15:34

我需要一个批处理脚本来检查是否有两个以上的文件夹具有相同的日期字符串,并且在20171113.22442420171113.22442120171113.224412之类的文件夹名称中,.总是剩下8位数字.

I need a batch script to check if there are more than two folders with same date string with always 8 digits left to . in folder name like 20171113.224424, 20171113.224421 and 20171113.224412.

批处理文件应使用相同的日期字符串保留最新的两个文件夹,并使用文件夹创建日期(而不是上次修改日期)删除所有其他较旧的文件夹.

The batch file should keep the newest two folders with same date string and delete all other older folders with using the folder creation date instead of last modification date.

对于上面创建日期等于上次修改日期的示例,要删除的文件夹为:

For the example above with creation date being equal the last modification date the folders to delete are:

20171113.224424
20171112.224424
20171111.224424

如果两个文件夹的创建日期相同,则应删除点号后面编号较小的文件夹.

When two folders have the same creation date, the one with lower number after the dot should be deleted if that is possible.

其余文件夹为:

20171113.224421
20171113.224412
20171112.424424
20171112.221424
20171111.224428
20171111.224427

我尝试了很多代码,但是我并没有在这里发布所有代码.

I tried a lot of codes, but I don't post them all here.

我有列出目录中所有文件夹的代码,但是找不到用相同的前8个字母对文件夹进行分组的方法:

I have code which list all folders in directory, but can't find the method to group the folders with same first 8 letters:

@echo off
set back=%cd%
for /d %%i in (d:\backup\*) do (
    cd "%%i"
    echo current directory:
    cd
    pause
)
cd %back%

如果编写了常规分组,我编写了跳过最后10行的代码,并如上所述删除了不需要的文件夹:

I wrote code to skip last 10 lines if there a regular grouping and delete the folders that I don't need as described above:

@echo off
for /F "skip=10 delims=" %%I in ('dir "d:\backup\*" /AD /B /O-N 2^>nul') do rd /Q /S "d:\backup\%%I"

推荐答案

此任务的批处理文件为:

A batch file for this task would be:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "BackupFolder=D:\backup"
set "LastDate="
for /F "delims=." %%I in ('dir "%BackupFolder%\????????.*" /AD /B /ON 2^>nul') do (
    if not "!LastDate!" == "%%I" (
        for /F "skip=2 delims=" %%D in ('dir "%BackupFolder%\%%I.*" /AD /B /O-D-N /TC') do rd /Q /S "%BackupFolder%\%%D"
        set "LastDate=%%I"
    )
)
endlocal

第一个外部 FOR 在单独的命令过程中执行,该过程以cmd /c为背景,在第一个括号中指定的 DIR 命令行在后台运行,并捕获输出的所有内容> DIR 处理 STDOUT ,以便以后逐行处理它.

The first, outer FOR executes in a separate command process started with cmd /c in background the DIR command line specified in first parenthesis and captures everything output by DIR to handle STDOUT for processing it later line by line.

使用的 DIR 命令输出

  • 仅由于/AD(属性目录)而与通配符模式????????.*相匹配的目录
  • 由于/B(裸格式),其名称仅带有路径而没有路径
  • 由于/ON而按名称排序(按名称排序).
  • only directories matching wildcard pattern ????????.* because of /AD (attribute directory)
  • with only their names without path because of /B (bare format)
  • sorted by name because of /ON (ordered by name).

当前备份文件夹中可能不包含与此模式匹配的文件夹.在这种情况下, DIR 将输出一条错误消息以处理 STDERR ,由于包含 file 而不是目录.该可能的错误消息被重定向到设备 NUL 进行抑制.

It is possible that the backup folder currently contains no folder matching this pattern. In this case DIR would output an error message to handle STDERR which would be confusing because of containing file instead of directory. This possible error message is redirected to device NUL to suppress it.

阅读有关使用命令重定向操作符的Microsoft文章, 2>nul的说明.当Windows命令解释器在执行命令 FOR 之前处理此命令行时,重定向操作符>必须在 FOR 命令行上转义字符^进行转义,以将其解释为文字字符. >在后台启动的单独命令过程中执行 DIR 命令行.

Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the DIR command line in a separate command process started in background.

外部 FOR 处理捕获的行,而忽略空行和以分号开头的行.这样的行在这里不存在,所以没有问题.每行(其他)都使用.作为分隔符分成两个字符串.仅将每行第一行.左边的第一个字符串分配给循环变量I,该变量在接下来执行的命令行中使用.

Outer FOR processes the captured lines with ignoring empty lines and lines starting with a semicolon. Such lines do not exist here, so no problem. Each (other) line is split up into two strings using . as delimiter. Only the first string left to first . of each line is assigned to loop variable I which is used in the command lines executed next.

在这里重要的是使用命令 DIR 来获取由 FOR 处理的目录列表,而不是在循环执行期间进行修改,而不是使用for /D来读取下一个目录在循环的每次迭代中直接从文件系统中命名.目录列表在循环执行期间更改.使用for /D时,可能会由于处理目录时目录列表的更改而跳过了某些目录.

It is important here to use command DIR to get a directory list processed by FOR not being modified during loop execution instead of using for /D which would read next directory name directly from file system on each iteration of the loop. The list of directories changes during loop execution. On using for /D it could happen that some directories are skipped because of directory list changes while processing the directories.

IF 条件使用延迟的环境变量扩展进行简单的区分大小写的字符串比较,以将先前处理的文件夹的日期字符串与当前文件夹进行比较.仅在最后处理的文件夹的日期与当前文件夹的日期之间的差值执行内部循环.这种 IF 条件只是为了使文件夹删除过程更快一些.

The IF condition makes a simple case-sensitive string comparison using delayed environment variable expansion to compare the date string of previous processed folder(s) with the current folder. Only on difference between date of last processed folder(s) and date of current folder the inner loop is executed. This IF condition is just for making the folder deletion process a little bit faster.

在这里使用延迟环境环境变量扩展没有问题,因为备份文件夹中没有文件夹在文件夹名称中包含感叹号.

It is no problem here to use delayed environment environment variable expansion as no folder in backup folder contains an exclamation mark in folder name.

第二个内部 FOR 循环也运行 DIR 命令以获取包含当前文件夹的日期字符串及其名称的目录列表,但这一次是相反的如果两个或多个文件夹具有相同的创建日期,则由于/O-D-N(按日期反向排序,下一个按名称反向排序)和/TC(时间:创建),因此按创建日期排序和按名称第二次反向排序具有相同的创建日期.反向日期顺序表示最新目录首先输出,最旧目录最后输出.

The second, inner FOR loop runs also command DIR to get a list of directories with the date string of current folder with just their names, but this time first reverse ordered by creation date and second reverse ordered by name in case of two or more folders have same creation date because of /O-D-N (ordered reverse by date and next reverse by name) and /TC (time: creation). Reverse date order means newest directory is output first and oldest is output last.

内部的 FOR 循环通过跳过前两行来处理 DIR 输出的捕获行,这意味着忽略了两个最新的文件夹.其他行的处理不会由于delims=(空分隔符列表)而导致行不拆分,因此,由 DIR 输出的完整文件夹名称将分配给循环变量D.

The inner FOR loop processes the captured lines output by DIR with skipping the first two lines which means ignoring the two newest folders. The other lines are processed without splitting the line up because of delims= (empty delimiter list) and therefore the complete folder name as output by DIR is assigned to loop variable D.

由于/Q,命令 RD 会自动删除名称保留在循环变量D中的文件夹,由于/S,所有文件和子文件夹都将被删除.

The command RD deletes the folder of which name is hold in loop variable D quietly because of /Q with all files and subfolders because of /S.

然后将当前文件夹的日期字符串分配给环境变量LastDate,以跳过具有相同日期字符串的外部 FOR 的目录列表中的所有文件夹.

Then the date string of current folder is assigned to environment variable LastDate to skip all folders in directory list of outer FOR with same date string.

在不使用延迟的环境变量扩展的情况下也可以使用单个命令行的速度稍慢一些,这对于名称为!的文件夹也适用.

It would be also possible to use a single command line without usage of delayed environment variable expansion being a bit slower which would also work for folders with ! in name.

@for /F "delims=." %%I in ('dir "D:\backup\????????.*" /AD /B /ON 2^>nul') do @for /F "skip=2 delims=" %%D in ('dir "D:\backup\%%I.*" /AD /B /O-D-N /TC') do @rd /Q /S "D:\backup\%%D"

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • rd /?
  • set /?
  • setlocal /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • rd /?
  • set /?
  • setlocal /?

更新:

增强版本,用于在删除备份目录之前记录具有完整路径的所有文件的名称.

Enhanced version logging the names of all files with full path before deletion of a backup directory.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "BackupFolder=D:\backup"
set "LastDate="
set "LogFile=%BackupFolder%\DeletedFiles.log"
for /F "delims=." %%I in ('dir "%BackupFolder%\????????.*" /AD /B /ON 2^>nul') do (
    if not "!LastDate!" == "%%I" (
        for /F "skip=2 delims=" %%D in ('dir "%BackupFolder%\%%I.*" /AD /B /O-D-N /TC') do (
            dir "%BackupFolder%\%%D" /A-D /B /ON /S >>"%LogFile%" 2>nul
            rd /Q /S "%BackupFolder%\%%D"
        )
        set "LastDate=%%I"
    )
)
endlocal

单个命令行版本:

@for /F "delims=." %%I in ('dir "D:\backup\????????.*" /AD /B /ON 2^>nul') do @for /F "skip=2 delims=" %%D in ('dir "D:\backup\%%I.*" /AD /B /O-D-N /TC') do @dir "D:\backup\%%D" /A-D /B /ON /S >>"D:\backup\DeletedFiles.log" 2>nul & rd /Q /S "D:\backup\%%D"

这篇关于如何在具有多个文件夹组的文件夹中删除一组文件夹中最旧的文件夹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆