Loops 当文件名与模式列表不匹配时,批处理脚本将删除文件

Loops 当文件名与模式列表不匹配时,批处理脚本将删除文件,loops,batch-file,cmd,glob,Loops,Batch File,Cmd,Glob,我想删除目录中的所有文件,但名称与特定模式匹配的文件除外。此目录中文件类型的典型示例如下: Bookmarks.xml----删除 DownloadMeta.xml----删除 logfile.log----删除 1745388844.idx----删除 TS1.c.pickle----删除 TS1.prm.bak----删除 !!clear.bat--保持 .gitignore---保留 BookFlight.c---保留 检查行程.c---保留 组合的\u TS1.c---保持 pre_c

我想删除目录中的所有文件,但名称与特定模式匹配的文件除外。此目录中文件类型的典型示例如下:

  • Bookmarks.xml----删除
  • DownloadMeta.xml----删除
  • logfile.log----删除
  • 1745388844.idx----删除
  • TS1.c.pickle----删除
  • TS1.prm.bak----删除
  • !!clear.bat--保持
  • .gitignore---保留
  • BookFlight.c---保留
  • 检查行程.c---保留
  • 组合的\u TS1.c---保持
  • pre_cci.c---保持
  • TS1.prm---保持
  • TS1.usr---保持
  • vuser_end.c----保留
  • vuser_init.c--保留
  • globals.h---保持
  • ScriptUploadMetadata.xml--保留
我想在模式列表中保留具有名称的文件:

list_to_ignore = ["!clear.bat", ".gitignore", "*.usr", "default.cfg", 
                    "default.usp", "*.c", "*lobals.h", "*custom_body.h", 
                    "*body_variables.txt", "*loadMetadata.xml", "*.prm" ]
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BatchFileName=%~nx0"
set "BatchFileName=%BatchFileName:.=\.%"
for /F "eol=| delims=" %%I in ('dir "%~dp0" /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R /X /V /C:"!clear\.bat" /C:"\.gitignore" /C:"^.*\.usr" /C:"default\.cfg" /C:"default\.usp" /C:"^.*\.c" /C:"^.*lobals\.h" /C:"^.*custom_body\.h" /C:"^.*body_variables\.txt" /C:"^.*ploadMetadata\.xml" /C:"^.*\.prm" /C:"%BatchFileName%"') do @del /A /F "%~dp0%%I"
endlocal
例如:

  • 文件TS2.c.pickle与列表中的任何项都不匹配,因为它以.pickle扩展名结尾。应该删除它

  • filesomefile.c匹配“*.c”模式,因为它以.c结尾。应该保留它

  • 文件Metadata.xml与任何模式都不匹配,因为它在开头缺少前缀“load”。应该删除它

  • 文件Globals.h匹配“lobals.h”模式。应保留该文件

以下是我尝试过的:

@echo off
FOR /d %%a in ("./*") DO rd "%%a" /q /s
FOR %%i in (*.*) DO ^
if not "%%i"=="!clear.bat" ^
if not "%%i"==".gitignore" ^
if not "%%i"=="*.usr" ^
if not "%%i"=="default.cfg" ^
if not "%%i"=="default.usp" ^
if not "%%i"=="*.c" ^
if not "%%i"=="*lobals.h" ^
if not "%%i"=="*custom_body.h" ^
if not "%%i"=="*body_variables.txt" ^
if not "%%i"=="*ploadMetadata.xml" ^
if not "%%i"=="*.prm" ^
DEL /s /q "%%i"
pause

希望这是有意义的。如果这不是一个合适的问题,请告诉我


非常感谢

这可以通过批处理文件中的以下命令行来完成:

@for /F "eol=| delims=" %%I in ('dir "%~dp0" /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /X /V /C:"!clear.bat" /C:".gitignore" /C:"BookFlight.c" /C:"CheckItinerary.c" /C:"combined_TS1.c" /C:"pre_cci.c" /C:"TS1.prm" /C:"TS1.usr" /C:"vuser_end.c" /C:"vuser_init.c" /C:"globals.h" /C:"ScriptUploadMetadata.xml" /C:"%~nx0"') do @del /A /F "%~dp0%%I"
此命令行导致在后台启动另一个命令进程,并将
%ComSpec%/c
'
之间的命令行作为附加参数附加。在安装到
c:\Windows
的Windows中执行此命令,批处理文件的完整限定文件名为
c:\Temp\Test.bat

C:\Windows\System32\cmd.exe /c dir "C:\Temp\" /A-D /B 2>nul | C:\Windows\System32\findstr.exe /I /L /X /V /C:"!clear.bat" /C:".gitignore" /C:"BookFlight.c" /C:"CheckItinerary.c" /C:"combined_TS1.c" /C:"pre_cci.c" /C:"TS1.prm" /C:"TS1.usr" /C:"vuser_end.c" /C:"vuser_init.c" /C:"globals.h" /C:"ScriptUploadMetadata.xml" /C:"Test.bat"
DIR处理标准输出的输出(标准输出)

  • 由于选项
    /A-D
    (属性不是目录),仅显示文件名
  • 匹配默认通配符模式
    *
    (任意文件名)
  • 在指定的目录
    C:\Temp
  • 使用裸格式,因为选项
    /B
    仅表示文件名和文件扩展名
在这种情况下,命令DIR实际上不可能输出错误消息,因为没有找到与这些条件匹配的目录项来处理STDERR(标准错误)因为此目录中必须有批处理文件。但是
2>nul
会将此错误消息重定向到处理在后台启动的命令进程的STDERR,以抑制它

DIR的输出通过
|
重定向到搜索的FINDSTRSTDIN(标准输入)

  • 不区分大小写,因为选项
    /I
  • 字面上是因为选项
    /L
  • 由于选项
    /X
  • 使用选项
    /C:
  • 并输出以处理后台命令的STDOUT,因为选项
    /V
    ,这意味着所有行都不是完全搜索的字符串
另请阅读Microsoft关于的文章,了解有关
2>nul
|
的解释。重定向运算符
|
必须在上使用插入符号
^
转义,以便在Windows命令解释器处理此命令时将命令行解释为文字字符在执行
FOR
的命令之前执行ne,该命令在后台启动的单独命令过程中使用findstr执行嵌入的dir命令行

FOR捕获后台命令进程的输出以处理STDOUT,并在启动
cmd.exe后逐行处理该输出,在完成命令行执行后终止自身

FOR跳过此处未出现的所有空行。FOR接下来将使用字符的普通空格和水平制表符作为字符串分隔符将每行拆分为子字符串。FOR将忽略以
开头的第一个子字符串上的一行;
是默认的行尾字符。否则,仅将第一个空格/制表符分隔的字符串分配给循环变量
I
,以便进一步处理

这里不需要这种行分割行为,因为文件名可以包含一个或多个空格,并且可以在0个或多个前导空格后以分号开头。因此,选项
eol=|
用于将竖线定义为行尾字符,任何文件名都不能包含该字符,选项
delims=
用于定义emp关闭将文件名拆分为子字符串的字符串分隔符列表

因此,DIR输出的每个文件名都不是指定为FINDSTR搜索字符串的字符串之一,它被完全分配给循环变量
I
,而for执行命令DEL,该命令删除由于使用opt而独立于隐藏文件的文件离子
/A
甚至是只读文件,因为选项
/F

重写命令行,以便将FINDSTR与正则表达式一起使用以筛选出文件名
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BatchFileName=%~nx0"
set "BatchFileName=%BatchFileName:.=\.%"
for /F "eol=| delims=" %%I in ('dir "%~dp0" /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R /X /V "!clear\.bat \.gitignore ^.*\.usr default\.cfg default\.usp ^.*\.c ^.*lobals\.h ^.*custom_body\.h ^.*body_variables\.txt ^.*ploadMetadata\.xml ^.*\.prm %BatchFileName%"') do @del /A /F "%~dp0%%I"
endlocal