您的代码的主要问题是变量扩展。在批处理文件中,当一个命令或一个命令块(包含在括号中的几个命令)被获得时,它们被解析并执行。在解析阶段,变量读取操作(%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
但是,正如你的情况,你只更改两个值,值是不相关的变量的值,它仅仅是一个标志,你可以忽略延迟扩展和变量中的真正价值和使用替代语法if defined
来测试变量是否包含值。你true/false
可以是defined/not defined
测试
@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
如果扩展匹配任何的参数,变量的内容被删除,也就是现在的变量是不确定的。
编辑适应脱线的评论
当与filesytem元素处理,就可以看到这个文件/文件夹选择意外行为。
不遵循8.3
传统命名的文件和文件夹(名称最多8个字符,最多3个扩展名,无特殊字符,无空格)具有所谓的长名称,但它们还有一个简短的8.3
名称与长名称关联。可以在dir
命令中使用/x
开关。
虽然不是直接可见,但是当完成通配符搜索时会检查这些短名称,从而导致选择的文件/文件夹的长文件名或扩展名与所请求的通配符表达式不匹配,但名称或扩展名与通配符匹配。
在需要的情况下内for
循环要处理的短名称或扩展,在for
替换参数使用的改性剂(例如,%%f
)来检索他们是
%%~snxf Short name and short extension of the element being referenced by %%f
%%~snf Short name of the element being referenced by %%f
%%~sxf Short extension of the element being referenced by %%f
确实很好。或许你应该加上关于lfn vs sfn的警告。 – Magoo
@Magoo,因为代码对于短文件名/扩展名没有任何问题。搜索不是使用文件的扩展名来完成的,'%%〜xf'如果存在,它将检索长扩展名。 –
@MCND哇!非常感谢,这是非常翔实的! – Igor