-1

我正在使用 cmd 批处理代码删除文件F:\Work夹内的所有文件,除了一个文件txt1.txt,该文件夹包含两个文件txt1.txttxt2.txt.

这是我正在使用的批处理代码:

forfiles /p "f:\Work" /s /m *.*  /C "cmd /c if not @file==txt1.txt del @path" 

它同时删除txt1.txttxt2.txt。怎么了?

4

2 回答 2

0

使用 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
于 2021-08-04T02:51:04.233 回答
0

无需forfiles为您的任务使用,标准for循环非常适合:

for /R "F:\Work" %%I in (*) do if /I not "%%~nxI"=="txt1.txt" del "%%~I"

但是,如果您坚持使用forfiles,则:

  1. 不要指定掩码/M *.*而是使用掩码/M *(无论如何这是默认值),因为前者会跳过没有扩展名的文件。
  2. 注意forfiles迭代文件和目录,因此/C "cmd /C if @isdir==FALSE …"仅用于处理文件。
  3. forfiles'字符串内的转义引号/C,如\"or 0x22。(我更喜欢后者,因为"in\"仍然可以被命令处理器识别,这^在某些情况下可能需要额外的 -escaping,可能会导致非常复杂且难以辨认的转义序列。)
  4. 请注意,所有与文件名相关的@变量都返回带引号的值,因此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"
于 2021-08-04T10:08:51.357 回答