变量内部的批处理变量在调用时不起作用

时间:2013-11-30 12:13:33

标签: variables batch-file cmd double

Inside Test.txt在第一行读取一个URL,还有更多,但为此它不重要。

setlocal EnableDelayedExpansion
set browser=chrome.exe
set i=0
for %%f in (Test.txt) do (
    set i=0
    for /F "delims=" %%l in (%%f) do (
        set /A i+=1
        set line!i!=%%l
        ))
::the above read the contents of Test.txt and saved each line to a different Variable made up of two variables
set x=0
:ReadLines
if %x% gtr %i% (
    goto Completed)
set /a x+=1
set /a odd=%x%%%2
if %odd%==1 (
    set Address=!line%x%!
    echo !Line%x%!
    ::the above echo's back the URL from the Text File
    echo %Address%
    ::but the above here, echo's back nothing at all,(which then is either echo is off or echo is on) even though %Address% has been set to !Line%x%!
    pause
    ::when i try to use !Line%x%! in my code, like the start code below, it returns nothing instead of the URL
    start %browser% %Address% >nul 2>&1
    start %browser% !Line%x%! >nul 2>&1
    ::neither start code works unfortunately and that's my ISSUE
    ping localhost -n 2 >nul
    goto ReadLines
)
:Completed
::Continue or Whatever...

所以我的问题:有人知道为什么,当回应时,!行%x%!返回它应该的值,但是什么时候                         称为uppon的命令,例如,启动%browser%%Address%,它什么都不返回?                         顺便说一句,您可以运行上面的代码,只需在名为“Test.txt”的txt文档中添加一些链接,您就会看到我自己的问题 对不起,如果它看起来对任何人都很难看,我真的只是为了某人而把它扔到一起,但后来遇到了这个错误,需要为他们解决这个问题。需要任何帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

@ECHO OFF
setlocal EnableDelayedExpansion
set browser=chrome.exe
set i=0
for %%f in (q20300102.txt) do (
    set i=0
    for /F "delims=" %%l in (%%f) do (
        set /A i+=1
        set line!i!=%%l
        ))
::the above read the contents of Test.txt and saved each line to a different Variable made up of two variables
set x=0
:ReadLines
if %x% gtr %i% (
    goto Completed)
set /a x+=1
set /a odd=%x%%%2
if %odd%==1 (
    set Address=!line%x%!
    echo !Line%x%!
    REM the above echo's back the URL from the Text File
    echo %Address%
    REM but the above here, echo's back nothing at all,(which then is either echo is off or echo is on) even though %Address% has been set to !Line%x%!
    REM pause
    REM when i try to use !Line%x%! in my code, like the start code below, it returns nothing instead of the URL
    ECHO start %browser% %Address%
    ECHO start %browser% !Line%x%!
    REM neither start code works unfortunately and that's my ISSUE
    ECHO ping localhost -n 2
)
goto ReadLines
:Completed
::Continue or Whatever...
GOTO :EOF

基本delayedexpansion问题。在任何复合语句(即带括号的括号语句组)中,%var%的任何出现在语句为PARSED时被var的值替换,然后执行它。

因此,当x = 1时,odd将被设置为1,语句组将被解析,echo %Address%%address%替换为{{THEN-current值} address 1}} - 但address尚未分配值,因为代码只是PARSED - 它尚未运行。

同样,start %browser% %Address%browser的值且该值已被替换,但未分配address,因此被[nothing]替换。

在带括号的代码的末尾,哟返回:readlines x=1。这会增加并x被分配2。就我所经历的情况而言,这并不奇怪,因此将跳过整个括号内的代码并批量继续执行以下行。在批处理中,到达标签不会“结束程序”,所以它只需收费并火箭发送到文件的末尾。

在上面的代码中,我已经

  1. 将文件名设置为q20300102,txt以适合我的系统。
  2. ::注释样式替换为REM,因为在某些实现中,损坏标签(:: - comment)会导致复合语句终止。
  3. 删除了重定向器以允许STARTPINGECHO编辑(并插入ECHO关键字)
  4. GOTO readlines移到化合物的外面,无论x是否为奇数,都会强制循环。
  5. 由于您没有在Test.txt中提供任何行的示例,因此我创建了自己的q20300102.txt,其中包含:

    Address_one
    Address_two
    Address_three
    Address_four
    Address_five
    Address_six
    Address_seven
    Address_eight
    Address_nine
    

    并运行以上,产生了

    Address_one
    ECHO is off.
    start chrome.exe 
    start chrome.exe Address_one
    ping localhost -n 2
    
    Address_three
    Address_one
    start chrome.exe Address_one
    start chrome.exe Address_three
    ping localhost -n 2
    
    Address_five
    Address_three
    start chrome.exe Address_three
    start chrome.exe Address_five
    ping localhost -n 2
    
    Address_seven
    Address_five
    start chrome.exe Address_five
    start chrome.exe Address_seven
    ping localhost -n 2
    
    Address_nine
    Address_seven
    start chrome.exe Address_seven
    start chrome.exe Address_nine
    ping localhost -n 2
    

    (我已经通过迭代打破了实际输出以获得更多清晰度)

    所以 - 响应是

    Linex内容
    地址内容(注意 - 当(声明)为PARSED时) 开始语句,包括刚才描述的元素 Ping声明

    所以这应该让你走上解决问题的道路......

答案 1 :(得分:0)

简而言之:“您需要使用延迟扩展才能获得在块中修改的变量的值”;这是批处理文件中的基本变量管理行为:

if %odd%==1 (
    set Address=!line%x%!        <- "Address" variable was modified inside this block

    - - - - - -

    echo %Address%               <- This not work, you need Delayed Expansion here:
    echo !Address!

    - - - - - -

)

答案 2 :(得分:0)

1 - 除非您打算迭代一组文件,否则您的%%f循环不必要。如果您打算迭代一组文件,那么第二个set i=0将重置每个文件的计数器。

2 - 如前面的答案中所述,当一个代码块(开括号和右括号之间的所有内容)被引用时,每个变量都被替换为其当前值(在读取块时!)并且所有块都被执行一次或多次不更改变量,因为正在执行的代码不包含变量,只包含其值。此行为有两个例外:当延迟扩展处于活动状态时引用为!var!的变量,以及for命令中声明的contorl变量。

没有什么可以添加到其他答案为什么您的代码有问题。 Magoo和Aacini的答案根据延迟扩展的变量的正确使用情况反映出问题所在。需要使用延迟扩展sintax访问块内修改的每个变量以检索修改后的值。

以下代码反映了另一个选项,使用for变量来避免延迟扩展问题。

@echo off
setlocal EnableDelayedExpansion

    set "i=0"
    for /F "delims=" %%l in (test.txt) do (
        set /A "i+=1"
        set "line!i!=%%l"
    )

    for /l %%x in (1 1 %i%) do (
        set /a "odd=%%x %% 2"
        if !odd!==1 (
            set "Address=!line%%x!"
            echo !line%%x!
            echo !Address!
            echo ---------------
        )
    )