Batch,Variable在设置后消失

时间:2014-10-31 00:59:32

标签: batch-file batch-processing

我已经构建了一组代码,我希望它能实现以下目标:

  1. 从文本文件中拉出要通过for循环处理的文件列表(很简单)
  2. 从令牌中获取文件名并将其设置为变量
  3. 对于该文件,取每行文本并将其设置为自己的变量。
  4. 获取变量并使用逗号分隔将它们回显到单行中的文本文件
  5. 我的输入(%tlst%)文件很简单,包含5个文件名列表,每个记录都驻留在自己的行上:

    tran.txt1
    tran.txt2
    tran.txt3
    tran.txt4
    tran.txt5 
    

    这些文件中的每一个都包含10行,其中有一行信息,类似于以下内容:

    12345678910111476
    2014123456789813186313338
    20141030
    20141030
    840
    3597
    840
    3597
    www.test.com
    6068
    

    我希望我的结果看起来是5行回显到一个新文件(test.txt),如下所示:

    12345678910111476, 2014123456789813186313338, 20141030, 20141030, 840, 3597, 840, 3597, www.test.com, 6068
    

    这是我目前的代码:

    @echo=on
    Call :Start > c:\temp\test.log 2>&1
    :Start
    set tlst=C:\temp\test\tlist.txt
    For /F "tokens=*" %%H in (%tlst%) Do (
        set Z=%%H
        set Counter=1
        echo %Z%
        echo %Counter%
        For /F "tokens=*" %%x in (%Z%) Do (
            set "Line_!Counter!=%%x"
            echo "Line_!Counter! is %%x 
            set /a Counter+=1
        )
        set /a NumLines=Counter - 1
        Echo %Line_1%, %Line_2%, %Line_3%, %Line_4%, %Line_5%,  %Line_6%, %Line_7%, %Line_8%, %Line_9%, %Line_10%, >> C:\temp\test.txt
        :: or, for arbitrary file lengths:
        for /l %%x in (1,1,%NumLines%) do echo %%x is !Line_%%x!
    )
    

    我目前遇到的是我从第6行的令牌中设置的变量似乎没有坚持......变量看起来像是设置了,但在下面的第8行中我尝试回显变量为空,我的下一个For循环显示%Z%变量为(NULL)。我还尝试将%% H标记回显到临时文件中,然后通过

    设置变量
    set /p Z=<tempfile 
    

    但两种方法似乎都有相同的结果。

    我也尝试在我的通话中添加SETLOCAL EnableExtensions EnableDelayedExpansion,但我再也看不到任何变化。我现在有点失落,所以任何帮助都会受到赞赏。这是我正在提取的日志文件中的一个片段,每个条目返回相同的错误,第二行只有一个不同的记录:

    (
    set Z=tran.txt1  
     set Counter=1  
     echo   
     echo   
     For /F "tokens=*" %x in ((null)) Do (
    set "Line_!Counter!=%x"  
     echo "Line_!Counter! is %x   
     set /a Counter+=1 
    )  
     set /a NumLines=Counter - 1  
     Echo , , , , ,  , , , , ,  1>>C:\temp\test.txt  
     for /L %x in (1 1) do echo %x is !Line_%x! 
    ) 
    

    如果我错过任何细节,我会提前抱歉,我尽可能清楚完整地了解我正在努力实现的细节以及正在发生的过程。

1 个答案:

答案 0 :(得分:0)

你有点认识到你需要延迟扩展,但你没有正确使用它。

正常变量扩展%Counter%在解析语句时发生,并且整个带括号的DO()块在一次传递中被解析。所以该值在循环内是恒定的。您需要启用延迟扩展并改为使用!Counter!!Z!!Line_1!!Line_2!

也是如此

当您可以使用!Z!代替时,我不明白为什么您会为%%H而烦恼。

你不需要一堆Line_n变量 - 你可以简单地将每个值附加到前一个值的末尾。

你应该在你的CALL之后放一个EXIT / B,这样你就不会第二次进入子程序了。但是你可以简单地在整个循环中加上括号并改为重定向。

以下内容应该有效:

@echo off
setlocal enableDelayedExpansion
set "tlst=c:\temp\test\tlist.txt"

>"c:\temp\test.log" 2>&1 (
  for /f "usebackq delims=" %%F in ("%tlst%") do (
    set "ln=,"
    for /f "usebackq delims=*" %%L in ("%%~F") do (
      set "ln=!ln!,%%L"
    )
    echo(!ln:~2!
  )
)

我使用了USEBACKQ选项,以防你得到包含空格的文件路径。

我使用不需要的字符初始化ln变量,然后将其删除,以便即使文件中没有值也定义变量。

请注意,如果启用了延迟扩展且值包含!,则FOR变量扩展将会损坏。如果您可能遇到!,那么必须在循环内打开和关闭延迟扩展,如下所示:

@echo off
setlocal disableDelayedExpansion
set "tlst=c:\temp\test\tlist.txt"

>"c:\temp\test.log" 2>&1 (
  for /f "usebackq delims=" %%F in ("%tlst%") do (
    set "ln=,"
    for /f "usebackq delims=*" %%L in ("%%~F") do (
      setlocal enableDelayedExpansion
      for "delims=" %%A in ("!ln!") do (
        endlocal
        set "ln=%%A,%%L"
      )
    )
    setlocal enableDelayedExpansion
    echo(!ln:~2!
    endlocal
  )
)