Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?

指南:

每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包

澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。

(请参见:Windows批处理文件:.bat vs .cmd?)


当前回答

稍后可以使用call对名称求值,从而得到一些有用的属性。

call set SomeEnvVariable_%extension%=%%%somevalue%%%

使用调用来设置名称依赖于其他变量的变量。如果与某些变量命名规则一起使用,则可以通过使用谨慎的命名规则来模拟数组或字典等数据集合。somevalue周围的三个%是这样的,它将在调用之后和调用set之前计算为一个变量名,周围是一个%。这意味着一行中的两个%转义为一个%字符,然后它将再次展开它,因此somevalue实际上是一个名称指针。

call set TempVar=%%SomeEnvVariable_%extension%%%

将它与一个临时变量一起使用以检索值,然后可以在逻辑中使用该值。这在与延迟变量展开一起使用时非常有用。

要正确使用此方法,需要启用延迟变量扩展。因为它在默认情况下是关闭的,所以最好在脚本中启用它,将其作为第一个指令之一:

setlocal EnableDelayedExpansion

其他回答

FOR命令!虽然我讨厌写批处理文件,但我很感激它。

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

将解析myfile.txt中的每一行,忽略以分号开头的行,将每行的第2和第3个标记传递给for主体,标记由逗号和/或空格分隔。 注意for语句引用%i获取第二个令牌,引用%j获取第三个令牌,引用%k获取第三个令牌之后的所有剩余令牌。

你也可以用它来遍历目录、目录内容等等…

ENDLOCAL使用的行仍然解析局部变量。这就允许了以下技巧:

ENDLOCAL & SET MYGLOBAL=%SOMELOCAL% & SET MYOTHERGLOBAL=%SOMEOTHERLOCAL%

这是一种将结果传输到调用上下文的有用方法。具体来说,一旦ENDLOCAL完成,% somlocal%就超出了作用域,但那时% somlocal%已经展开,因此MYGLOBAL在调用上下文中使用局部变量赋值。

出于同样的原因,如果你决定这样做:

ENDLOCAL & SET MYLOCAL=%MYLOCAL%

您将发现新的MYLOCAL变量现在实际上是一个常规环境变量,而不是您希望它成为的局部变量。

PUSHD path

将您带到path指定的目录。

POPD

带您回到您“推”的目录。

变量的延迟展开(为了更好地度量,还加入了子字符串):

    @echo off
    setlocal enableextensions enabledelayedexpansion
    set full=/u01/users/pax
:loop1
    if not "!full:~-1!" == "/" (
        set full2=!full:~-1!!full2!
        set full=!full:~,-1!
        goto :loop1
    )
    echo !full!
    endlocal

子例程(输出42):

    @echo off
    call :answer 42
    goto :eof
:do_something
    echo %1
    goto :eof

子例程返回一个值(输出0、1、2,等等):

    @echo off
    setlocal enableextensions enabledelayedexpansion
    call :seq_init seq1
:loop1
    if not %seq1%== 10 (
        call :seq_next seq1
        echo !seq1!
        goto :loop1
    )
    endlocal
    goto :eof

:seq_init
    set /a "%1 = -1"
    goto :eof
:seq_next
    set /a "seq_next_tmp1 = %1"
    set /a "%1 = %seq_next_tmp1% + 1"
    set seq_next_tmp1=
    goto :eof