批处理文件按指定的扩展名删除文件

时间:2017-02-26 11:12:26

标签: batch-file

我需要删除所有未在参数中指定的扩展名的文件(.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

非常感谢有关如何使我的代码按预期运行的任何建议。

1 个答案:

答案 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