1

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

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

4

2 回答 2

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
于 2012-09-11T22:24:20.760 回答
1

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

使用FIND.EXE方法:

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

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

使用for方法:

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

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

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


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

注意setlocal enabledelayedexpansionendlocal线。SETLOCAL使所有变量都是临时的,因此仅在脚本执行期间存在,从而无需在脚本末尾清除每个变量。enableDelayedExpansion启用!符号的使用,允许像这样访问变量:!Variable!. 最后endLocal在脚本中指定 WHERE 所有临时变量都死掉或恢复到它们的预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 文件并将其连接到您的批处理文件,但我不知道。

于 2012-09-16T21:06:23.627 回答