根据批处理文件中的第二个变量调用变量

时间:2012-09-11 20:52:51

标签: windows batch-file cmd dos

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

@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中的单词数(或者它们是同一个单词),然后将该数字分配给变量?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

使用FIND.EXE方法:

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

使用find.exe的好处是可以通过任何文本文件找到zipps,就像疯了一样,并且它甚至会计算空行。

使用for方法:

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

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

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


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

注意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文件并将其连接到批处理文件,但我不知道。