【问题标题】:Call a variable based on a second variable in a batch file根据批处理文件中的第二个变量调用变量
【发布时间】:2012-09-11 20:52:51
【问题描述】:

我试图纠正的程序的过程是获取一个包含多个单词的文本文件,并将每个单词设置为一个变量,然后从列表集中回显一个随机变量。到目前为止,我的代码如下所示:

@Echo Off
Set _InputFile=config.txt
//Sets the Input file
For /F "tokens=1,2* delims=:" %%A IN (%_InputFile%) DO Set _Data%%A=%%B
//Sets each Word to a vairable from _data1 to _datax
set n=(random number code)
//Set's N to be a rational random number depending on the variables available
Echo _data%%n
//This is where i get stuck, i need to be able to echo _data(whatever number n is)
pause>nul

所以基本上我的主要问题是让文件根据另一个变量的值来回显一个随机变量。如果它比我正在尝试的更好/更合适,也将不胜感激。

其次(一个较小的问题)是否有任何方法可以确定 config.txt 中的单词数(或行数,因为这将是同一件事),然后将该数字分配给变量?

【问题讨论】:

    标签: windows batch-file cmd dos


    【解决方案1】:

    1) 使用 CALL 获得 2 个扩展阶段 - 一个在调用之前,一个在调用之后。这很慢,而且视觉上令人困惑。它也是最不可靠的,因为许多字符都有能力破坏结果。

    call echo %%_Data%n%%%
    

    2) 延迟扩展 - 更快、更容易遵循始终有效的方法。但是,如果 FOR 变量包含 ! 字符,延迟扩展将破坏 FOR 变量扩展。延迟扩展必须先开启才能使用。

    setlocal enableDelayedExpansion
    ::Above line must be executed sometime before the following
    echo !_Data%n%!
    

    2a) 如果n 变量设置在试图回显该值的同一个带括号的代码块中,则%n% 将不起作用。这个问题经常出现在 FOR 循环和 IF 语句中。它失败是因为 %n% 在解析整个块时展开,在 n 的值设置之前。诀窍是将!n! 的值传递给FOR 变量。

    setlocal enableDelayedExpansion
    for .... (
      set n = ....
      for %%N in (!n!) do echo !_Data%%N!
    )
    

    这里有一个方便的方法来获得一个介于 1 和 x 之间的伪随机数。它依赖于预定义的动态变量:RANDOM。

    set /a n=%random% %% x + 1
    

    如果在循环中计算值,那么您可能需要延迟扩展,以便每次迭代获得不同的数字。

    set /a n=!random! %% x + 1
    

    【讨论】:

      【解决方案2】:

      首先回答您的第二个问题,有几种方法可以快速获取文件中的行数。

      使用FIND.EXE 方法:

      for /f %%x in ('type %FileName% ^| find /v /c ""') do set Lines=%%x
      

      使用find.exe 的优点是可以通过任何文本文件找到 zipps,例如 mad,它甚至可以计算空白行。

      使用for 方法:

      for /f %%x in (%FileName%) do set /a count=count+1
      

      第二种方法的缺点是for 循环会自动跳过空白行。这种方法的优点是文件只需要访问一次。

      由于我们要读入文件的每一行并对其进行操作,因此在读入时对每一行进行计数会更有效率。


      在我们继续之前,我应该指出// 不是批处理中的注释标记,会导致错误。使用REM、REMark 命令或一对双冒号:: 来表示cmets。

      注意setlocal enabledelayedexpansionendlocal 行。 SETLOCAL 使所有变量都是临时的,因此仅在脚本执行期间存在,从而无需在脚本末尾清除每个变量。 enableDelayedExpansion 允许使用 ! 表示法,允许像这样访问变量:!Variable!。最后endLocal 指定脚本中的所有临时变量在哪里消失或恢复到它们之前的setlocal 值。如果您删除了endLocal 行,批处理文件结束时将隐含endlocal

      @Echo Off
      setlocal enabledelayedexpansion
      Set _InputFile=CONFIG.TXT
      set count=
      
      :: Sets each line to a vairable from _data1 to _data##
      For /F "tokens=1* delims=:" %%A IN (%_InputFile%) DO (
          set /a count=!count!+1
          Set "_Data!count!=%%A"
      )
      
      :: Create a random number between 1 and %count% using the MOD function in 'set /a'
      :: Equivalent to: SET /A n = aRandomNumber - ( theSameRandomNumber / %Count% ) + 1
      :: See http://en.wikipedia.org/wiki/Mod_function
      set /a n=%random% %% %count% +1
      
      :: Echo # of lines, a random # from 1 to %count%, and a random line from the file:
      echo.
      echo =================================================
      echo File is %count% lines deep
      echo Random #: %n%
      
      :: Print a random line of data
      :: We are taking advantage of Delayed Expansion and ! notation:
      Echo Random Line: "!_data%n%!"
      echo.
      
      :: Use SET to echo every line of data read in
      echo Whole Set of _data[#] data:
      set _data
      echo.
      
      endlocal
      

      要记住的一件事是CMD.EXE 带来了旧MS-DOS 固有的一些限制。在这种情况下,有两个重要的限制:

      1) 可用内存量受到严格限制。
      2) 设置环境变量使用CMD.EXE 会话可用的大量内存。

      这对您来说意味着您将被限制在创建大约 100 个_data 变量,因此无法将超过该点的数据保存到变量中。

      在旧版本的 Windows 中,您可以为批处理文件创建一个 .PIF 文件(在命令行输入 copy nul BatchName.PIF,然后在 Windows 资源管理器中右键单击它并选择属性)并更改将要占用的内存量运行时分配给它。我认为你甚至可以在 XP 下做到这一点,但我知道在 Windows 7 中你不能。虽然可以下载现有的 .PIF 文件并将其连接到您的批处理文件,但我不知道。

      【讨论】:

        猜你喜欢
        • 2018-03-25
        • 2021-10-21
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        • 1970-01-01
        • 2016-06-17
        相关资源
        最近更新 更多