我需要删除所有未在参数中指定的扩展名的文件(.sys文件除外)。问题在于我的变量的赋值。
以下是我的命令(重复道歉,不知道如何在这里使用或声明):
@echo off
cls
cd test
for %%f in (*.*) do (
set exist = false
for %%a in (%*) do (
if %%~xf == .%%a set exist = true
if %%~xf == .sys set exist = true
)
if %exist% == false (
del %%f
)
)
pause
非常感谢有关如何使我的代码按预期运行的任何建议。
答案 0 :(得分:3)
您的代码的主要问题是变量扩展。在批处理文件中,当一个命令或一个命令块(括在括号中的几个命令)被引用时,它们被解析然后执行。在解析阶段,变量读取操作(%var%
)将从替换为变量内部值的代码中删除。完成此操作后,将执行命令或块。
所有这些意味着当代码执行时,如果更改代码中的变量(exists
),则在同一命令/块内部无法检索更改的值,因为没有任何变量读操作,在开始执行阶段之前,只有变量中的值。
使用setlocal enabledelayedexpansion
可以避免这种情况。此命令允许您将用于从%var%
读取变量的语法更改为!var!
,向解析器指示变量扩展必须延迟直到命令执行,而不是在解析阶段。
因此,您的代码可能类似于
@echo off
setlocal enabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
if "!exist!"=="false" (
del "%%f"
)
)
pause
请注意
set var = value
已更改为set var=value
。空格很重要,您定义了一个名为var[space]
的变量,其值为[space]value
引用所有变量赋值以防止变量值中包含不需要的结束空格。如果包含空格,则==
测试可能会失败。小心这不是必需的,但这是一个好习惯。
包含引号以防止文件名或扩展名中的空格出现问题
%exists%
已更改为!exists!
,因此可以在同一个区块(for %%f
)
if
扩展名比较包括/i
开关,用于不区分大小写的测试。
您还应注意,启用延迟扩展时,!
字符会成为问题,因为解析器会将其视为变量读取操作的一部分。如果您有可能包含此字符的文件或扩展名,则延迟扩展是一个问题。它可以完成,但只需要在真正需要时启用延迟扩展,并在不需要时再次禁用。
@echo off
setlocal disabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
setlocal enabledelayedexpansion
if "!exist!"=="false" (
endlocal
del "%%f"
) else (
endlocal
)
)
pause
但是,在您的情况下,您只是更改两个值之间的变量值且值无关,它只是一个标志,您可以忽略延迟扩展和变量内的实际值,并使用替代语法{ {1}}测试变量是否包含值。您的if defined
可以是true/false
测试
defined/not defined
如果扩展名与任何参数匹配,则删除变量内容,即现在变量未定义。
编辑以适应Magoo的评论
在处理filesytem元素时,可以在文件/文件夹选择中看到意外行为。
不遵循@echo off
setlocal enableextensions disabledelayedexpansion
cd test
for %%f in (*) do (
set "removeFile=1"
for %%x in (sys %*) do (
if /i "%%~xf"==".%%~x" set "removeFile="
)
if defined removeFile del "%%f"
)
pause
传统命名的文件和文件夹(名称最多8个字符,扩展名最多3个,没有特殊字符,没有空格)具有所谓的长名称,但它们也有一个与长名称关联的短8.3
名称。可以使用8.3
命令中的/x
开关查看。
虽然不能直接看到,但在完成通配符搜索时会检查这些短名称,从而导致选择的文件/文件夹长文件名或扩展名与请求的通配符表达式不匹配,但短名称或扩展名与通配符匹配。
如果需要在dir
循环内处理短名称或扩展名,for
可替换参数(例如for
)中使用的修饰符可以检索它们
%%f