【问题标题】:Wondering whether I set variables successfully in a batch file想知道我是否在批处理文件中成功设置变量
【发布时间】:2019-04-26 01:27:32
【问题描述】:

我在 Windows 命令提示符下运行一个批处理文件,回显结果似乎正确。但是当我接下来处理数据时,结果显示其中一个文件不存在,但是,它之前的回声很好。

另外,运行批处理后,我尝试回显之前批处理中设置的变量,都失败了。我想知道为什么,我是否成功设置了变量。

setlocal ENABLEDELAYEDEXPANSION
for /f %%f in ('dir /ad /b ') do (
    echo %%f
    pause
    pushd %%f
    for /d "tokens=1,2 delims=:" %%a in ('dir /b *.a*.dat in %%f' ) do (
        set COM_DATA=%%a
        echo !COM_DATA!
        set COM_V=%%f\com-v.dat
        echo !COM_V!
        set COM_M=%%f\com-M.dat
        echo !COM_M!
     ::some data process
    )
    chdir
    popd
)
endlocal

我希望我可以回显所有变量。

【问题讨论】:

  • 全部失败是什么意思?提供详细信息。要在 DOS 中回显变量,请使用:echo %VARIABLE%.
  • 输入endlocal /?
  • 如果您对数据处理有疑问,为什么要省略嵌套循环的那部分?请你 edit your question 包括那个缺失的代码。同时,您应该打开命令提示符窗口,输入For /?Dir /?,读取每个的输出并根据需要进行更正。
  • 不要在代码块中使用::-style cmets,它们可能会导致意外行为!改用rem...

标签: windows batch-file cmd


【解决方案1】:

有很多错误。我建议打开命令提示符窗口,运行 for /? 并阅读命令 FOR 的输出帮助/文档。另请参阅 Microsoft 的 Windows Commands 文档,甚至更好的 SS64.com - A-Z index of the Windows CMD command line

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /D %%I in (*) do (
    echo Processing directory "%%~fI" ...
    pushd "%%I"
    for %%J in (*.a*.dat) do (
        set "COM_DATA=%%J"
        echo !COM_DATA!
        set "COM_V=%%I\com-v.dat"
        echo !COM_V!
        set "COM_M=%%I\com-M.dat"
        echo !COM_M!
        rem some data process
    )
    popd
)
endlocal

阅读this answer 了解有关命令SETLOCALENDLOCAL 的详细信息。第二行是必需的,因为命令块内的环境变量定义也从命令块内引用。缺点是包含一个或多个! 的目录和文件名由于启用了delayed expansion 而未被此批处理文件正确处理。

最好在第二行末尾使用DisableDelayedExpansion而不是EnableDelayedExpansion,并且不要定义环境变量COM_DATACOM_VCOM_M,但在未显示的代码中使用%%J%%I\com-v.dat%%I\com-M.dat

外部FOR循环在当前目录中搜索任何非隐藏的子目录,并在每个找到的子目录上运行外部命令块内的命令。当前目录可以是任何目录。它不能是包含批处理文件的目录。使用字符串"%~dp0*" 代替* 来迭代批处理文件目录中的非隐藏子目录,这与启动批处理文件时的当前目录无关。仅使用* 时,不带路径的目录名称将分配给循环变量I。在使用"%~dp0*" 时,带有完整路径的目录名被分配给循环变量I

pushd "%%I" 使当前子目录成为执行批处理文件的命令进程的当前目录。

内部FOR循环在当前目录中搜索与指定通配符模式匹配的非隐藏文件,并将不带路径的文件名分配给循环变量J

不要使用:: 作为评论。这是一个无效的标签。命令块内的有效和无效标签会导致执行命令块时出现意外行为。有命令 REM (remark) 在批处理文件中写注释。请注意,带有命令 REM 的命令行与所有其他命令行一样,因此也由cmd.exe 处理和执行,如How does the Windows Command Interpreter (CMD.EXE) parse scripts? 中详细描述的那样

popd 在使用外部 FOR 继续处理批处理文件之前恢复初始当前目录。

endlocal 恢复初始环境,即丢弃setlocal 之后定义或修改的所有环境变量,恢复初始环境变量列表以及启动批处理文件时的初始当前目录以及命令扩展和延迟环境的初始状态变量扩展。

For 使用命令 DIR 两次迭代捕获的目录和文件名列表,从而完成相同的批处理文件,从而可以通过内部代码更改 *.a*.dat 文件列表 FOR循环并通过内部或外部FOR循环将子目录添加到当前或批处理文件目录。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir * /AD-H /B 2^>nul') do (
    echo Processing directory %%~fI ...
    pushd "%%I"
    for /F "eol=| delims=" %%J in ('dir *.a*.dat /A-D-H /B 2^>nul') do (
        set "COM_DATA=%%J"
        echo !COM_DATA!
        set "COM_V=%%I\com-v.dat"
        echo !COM_V!
        set "COM_M=%%I\com-M.dat"
        echo !COM_M!
        rem some data process
    )
    popd
)
endlocal

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • popd /?
  • pushd /?
  • rem /?
  • set /?
  • setlocal /?

阅读有关Using Command Redirection Operators 的Microsoft 文章,了解2>nul 的解释。重定向运算符 > 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令 FOR 之前处理此命令行时解释为文字字符> 在后台以%ComSpec% /C 启动的单独命令进程中执行嵌入的dir 命令行。

【讨论】:

    【解决方案2】:

    此示例与您提供的代码的用途相同,根据您提供的信息

    @Echo Off
    Set "COM_DATA=%%B"
    Set "COM_V=%%A\com-v.dat"
    Set "COM_M=%%A\com-M.dat"
    For /D %%A In (*)Do (
        Echo %%A
        For %%B In ("%%A\*.a*.dat")Do (
            Echo %COM_DATA%
            Echo %COM_V%
            Echo %COM_M%
            Rem Some data process
        )
    )
    Pause
    

    一旦您对运行代码的输出感到满意,(在任何修改之前),您可以根据需要删除所有 EchoRem 行。我没有使用过PushDPopD 命令,因为我认为没有理由使用它们,因为提供的信息。我还在For 块之外设置了变量,因为这意味着它们只需要设置一次,不是在每次迭代中,它消除了延迟扩展的需要。

    如果您的流程代码需要完整路径,您可能需要考虑将 %%A 的每个实例更改为 %%~fA

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 2013-01-19
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      相关资源
      最近更新 更多