为什么在for循环中设置的变量不存在

时间:2019-05-06 08:41:51

标签: batch-file

我编写了两个for循环来进行数据自动化。尽管变量在每个循环中都能很好地回显,但最后一步(使用精心编写的批处理的数据处理)不断给出错误,指出先前设置的变量不存在。

代码遍历目录下的子文件夹( q1,q2等)。对于每个子文件夹,都有另一个for循环来设置几个变量。我在循环中很好地回应了三个变量。 但是,在使用名为abc.rb的批处理时,错误为COM_M不存在。 实际上,错误是所有三个变量都不存在。

setlocal ENABLEDELAYEDEXPANSION
for /f %%f in ('dir /ad /b ') do (
    echo %%f
    pause
    pushd %%f
    for  %%a in (*.a*.dat) 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!
    )
    chdir
    set fig=someA
    set matrix=someB

    rem use a written batch (called abc.rb) to process data
    abc.rb  -a !COM_DATA!  -b !COM_V!  -c !COM_M! -d !fig! -e !matrix!

    popd
)
endlocal

谁能找到任何错误?谢谢!

2 个答案:

答案 0 :(得分:1)

我不确定为什么需要pushd进入目录,但据我所知,只需要一个for循环:

@echo off
setlocal enabledelayedexpansion
set "fig=someA"
set "matrix=someB"
for  /R %%a in (*.a*.dat) do (
    set "COM_DATA=%%a"
    echo !COM_DATA!
    set "COM_V=%%~dpacom-v.dat
    echo !COM_V!
    set COM_M=%%~dpacom-M.dat
    echo !COM_M!
    rem If abc.rb is is NOT a windows batch file, remove call below
    call abc.rb  -a "!COM_DATA!"  -b "!COM_V!"  -c "!COM_M!" -d !fig! -e !matrix!
)

如果您需要pushd(我对此表示怀疑)

@echo off
setlocal enabledelayedexpansion
set "fig=someA"
set "matrix=someB"
for  /R %%a in (*.a*.dat) do (
    pushd "%%~dpa"
    set "COM_DATA=%%a"
    echo !COM_DATA!
    set "COM_V=%%~dpacom-v.dat"
    echo !COM_V!
    set "COM_M=%%~dpacom-M.dat"
    echo !COM_M!
    rem If abc.rb is is NOT a windows batch file, remove call below
    call abc.rb  -a "!COM_DATA!"  -b "!COM_V!"  -c "!COM_M!" -d !fig! -e !matrix!
    popd
)

如果路径中包含空格,则双引号将有所帮助;如果程序存在问题,则可以将其删除:abc.rb -a !COM_DATA! -b !COM_V! -c !COM_M! -d !fig! -e !matrix!

答案 1 :(得分:0)

@echo off
setlocal ENABLEDELAYEDEXPANSION

set "fig=someA"
set "matrix=someB"
set "COM_V=com-v.dat"
set "COM_M=com-M.dat"

for /f %%f in ('dir /ad /b') do (
    echo %%f
    pause
    if exist "%%~f\*.a*.dat" (
        pushd "%%~f" && (
            for  %%a in (*.a*.dat) do (
                set "COM_DATA=%%~a"
                echo !COM_DATA!
            )
            chdir

            rem use a written batch called abc.rb to process data
            call abc.rb  -a "!COM_DATA!"  -b "!COM_V!"  -c "!COM_M!" -d "!fig!" -e "!matrix!"

            popd
        )
    )
)
endlocal

问题:

  1. 如果嵌套的for找不到匹配模式为*.a*.dat的文件,则变量COM_DATACOM_VCOM_M可能会不能用新值定义或更新。

  2. COM_DATA的值为文件名。 COM_VCOM_M的值是父文件夹名称和文件名,这是不一致的。基于当前目录,我认为文件名正确。这意味着COM_VCOM_M无需更改。

  3. 如果abc.rb是批处理文件,则您需要使用call作为解释器,以将控制权返回给主脚本。

更改:

  1. 测试文件模式是否存在,如果为true,则运行代码块中的代码。

  2. COM_VCOM_Mfor循环中移出,因为值永远不变。

  3. abc.rb作为批处理文件调用。

  4. figmatrixfor循环中移出,因为值永远不变。

  5. 设置变量的双引号并使用变量以避免空格,特殊字符等问题。

  6. pushd && (确保仅在成功更改目录后才运行括号中的代码。

  7. rem行中删除了括号。尽管rem行已解析并且可能导致语法错误,但它们可能不会引起问题。除非打算调试,否则建议避免在rem行中使用特殊字符。