我正在使用 cmd 批处理代码删除文件F:\Work
夹内的所有文件,除了一个文件txt1.txt
,该文件夹包含两个文件txt1.txt
和txt2.txt
.
这是我正在使用的批处理代码:
forfiles /p "f:\Work" /s /m *.* /C "cmd /c if not @file==txt1.txt del @path"
它同时删除txt1.txt
和txt2.txt
。怎么了?
我正在使用 cmd 批处理代码删除文件F:\Work
夹内的所有文件,除了一个文件txt1.txt
,该文件夹包含两个文件txt1.txt
和txt2.txt
.
这是我正在使用的批处理代码:
forfiles /p "f:\Work" /s /m *.* /C "cmd /c if not @file==txt1.txt del @path"
它同时删除txt1.txt
和txt2.txt
。怎么了?
使用 PowerShell 很容易做到这一点。PowerShell 可以在所有受支持的 Windows 系统上运行。当您对删除正确的文件感到满意时,请移除此WhatIf
开关。
Remove-Item -Path 'F:\work\*' -Recurse -Exclude txt1.txt,txt2.txt -WhatIf
如果您必须从 cmd.exe shell 或 .bat 文件脚本中运行,
powershell.exe -NoLogo -NoProfile -Command ^
"Remove-Item -Path 'F:\work\*' -Recurse -Exclude txt1.txt,txt2.txt" -WhatIf
无需forfiles
为您的任务使用,标准for
循环非常适合:
for /R "F:\Work" %%I in (*) do if /I not "%%~nxI"=="txt1.txt" del "%%~I"
但是,如果您坚持使用forfiles
,则:
/M *.*
而是使用掩码/M *
(无论如何这是默认值),因为前者会跳过没有扩展名的文件。forfiles
迭代文件和目录,因此/C "cmd /C if @isdir==FALSE …"
仅用于处理文件。forfiles
'字符串内的转义引号/C
,如\"
or 0x22
。(我更喜欢后者,因为"
in\"
仍然可以被命令处理器识别,这^
在某些情况下可能需要额外的 -escaping,可能会导致非常复杂且难以辨认的转义序列。)@
变量都返回带引号的值,因此if [not] @file==txt1.txt
永远不会 [不] 匹配,但if [not] @file==\"txt1.txt\"
会 [不],if /I [not] @file==\"txt1.txt\"
甚至会忽略大小写(如 escape "
like所说\"
)。因此正确的命令行是:
forfiles /S /P "F:\Work" /M * /C "cmd /C if @isdir==FALSE if /I not @file==\"txt1.txt\" del @path"
或者,使用替代引号转义和跳过掩码:
forfiles /S /P "F:\Work" /C "cmd /C if @isdir==FALSE if /I not @file==0x22txt1.txt0x22 del @path"