Command line 如何删除除特定文件以外的所有文件(批处理文件)

Command line 如何删除除特定文件以外的所有文件(批处理文件),command-line,batch-file,cmd,Command Line,Batch File,Cmd,我知道以前这里有类似的问题,但在我的情况下,在指定“删除”操作中要排除的文件时有特殊条件 文件名示例: A_001.xml A_002.xml B_001.xml B_002.xml B_003.xml C_009.xml D_002.xml 上述文件位于一个目录中,我需要删除所有文件,但保留文件名中计数器最高的每个文件的一个副本,即A_002.xm、B_003.xml、C_009.xml和D_002.xml 这可能吗?我是批处理文件创建新手,请帮助我。。我已经知道如何删除文件,甚至排除特定的文

我知道以前这里有类似的问题,但在我的情况下,在指定“删除”操作中要排除的文件时有特殊条件

文件名示例:

A_001.xml
A_002.xml
B_001.xml
B_002.xml
B_003.xml
C_009.xml
D_002.xml

上述文件位于一个目录中,我需要删除所有文件,但保留文件名中计数器最高的每个文件的一个副本,即A_002.xm、B_003.xml、C_009.xml和D_002.xml

这可能吗?我是批处理文件创建新手,请帮助我。。我已经知道如何删除文件,甚至排除特定的文件扩展名,但我不知道在这种情况下该怎么做

@ECHO OFF

SETLOCAL enabledelayedexpansion
::
:: establish target directory
:: initialise PREFIX to a name that's invalid in a filename
::
SET target=.
SET prefix=:
FOR /f "tokens=1*delims=_" %%i IN (
 'dir /b/a-d/o-n "%target%\*_*.xml'
 ) DO (
IF !prefix!==%%i ECHO DEL "%target%\%%i_%%j"
SET prefix=%%i
)
此解决方案依赖于目标目录中*xml文件的名称中是否存在“x”。我在批处理开发目录中的一些虚拟文件上测试了它,因此我对当前目录使用了

DIR命令生成目标目录中与模式
*.*.xml
匹配的文件列表
/b
开关表示
仅文件名
/a-d
表示
无目录名,即使它们与
匹配,
/o-n
表示
名称的顺序相反,名称将以零件的最高数值出现在
之后

FOR读取此输出,并将前缀分配给
%%i
,将文件名的其余部分分配给
%%j
,因为
前缀
被初始化为无效的文件名字符,它不可能与遇到的第一个文件的
%%i
匹配,因此将不会执行
DEL
。然后将存储最后遇到的前缀。只有当下一个文件名具有匹配的前缀时,才会执行
DEL

注意,我在
DEL
之前插入了
ECHO
关键字。这是发生错误时的安全装置。建议的
DEL
操作将报告给屏幕,而不是执行。一旦您确信批处理是正确的,请删除
ECHO
,删除操作将继续进行

要遵守的要点:

  • 有些编辑对删除或保留尾随内容相当傲慢 空间。通常,这是无害的,但在
    集合上是尾随空格
    批量命令可能导致混乱

对于xml文件的每个前缀,列出所有带有该前缀的文件,以获取列表中的最后一个文件。然后将最后一个标记为只读。删除除只读之外的所有给定模式。重置只读标志并重新设置下一个前缀。

若要通过尾随空格来避免问题,您只需将参数括在引号中:
set“target=。”
。之后的任何尾随空格都不会成为变量值的一部分。是的-您还可以将SET
(SET var=whatever)
括起来,这是我在删除变量
(SET var=)
非常重要时经常做的事,但我觉得这通常是多余的。也许我应该明确地使用皮带和支架的形式,因为它是关键-好的点。你只会被一个特定的陷阱抓住过一次-如果发生不止一次,也许你应该考虑改变你的职业,而不仅仅是你的编辑……或语言;)尽管有时我发现尝试编写健壮可靠的批处理文件是一种很好的爱好。我同意,除了这样做的挑战之外,没有具体的理由在批处理中这样做。谢谢Peter,这正是我所需要的:)非常感谢joojaa的回答。我确实认为你的答案很有用,但不幸的是,我必须选择Peter的答案作为我接受的答案,以获得更清晰的解释和更简单的代码。再次感谢,伙计:)当然没问题,但是我考虑不发布脚本,因为彼得已经发布了答案。只是我觉得彼得并没有直接回答这个问题。Peters代码只处理不删除最大数的问题,就像我处理内部循环中的4行一样(使用技巧)。但是,它不处理自动搜索每个集合并处理它。因此,虽然注释很好,但并不能真正回答问题。因为您仍然需要为每个组修复前缀等。但这也是为什么我懒得很好地注释任务的原因。
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set newprefix=_
for /F %%a in ('dir /on /b /a-d *.xml') do (
for /F "delims=_" %%i in ("%%a") do (
   IF NOT *%%i*==*!newprefix!* (
   for /F %%q in ('dir /on /b /a-d %%i*.xml') do set lastitem=%%q
   attrib +r !lastitem!  > NUL
   del /s /q %%i*.xml 1>NUL 2>NUL 
   attrib -r !lastitem!  > NUL
   set newprefix=%%i
   )
)
)