如何从文本文件中随机选择一行文本并将其设置在要使用的变量中?
3 回答
下面的 Batch 程序是 Eitan 的解决方案,稍作修改以运行得更快:
@echo off
setlocal EnableDelayedExpansion
set INPUT_FILE="test.txt"
:: # Count the number of lines in the text file and generate a random number
for /f "usebackq" %%a in (`find /V /C "" ^< %INPUT_FILE%`) do set lines=%%a
set /a randnum=%RANDOM% * lines / 32768 + 1, skiplines=randnum-1
:: # Extract the line from the file
set skip=
if %skiplines% gtr 0 set skip=skip=%skiplines%
for /f "usebackq %skip% delims=" %%a in (%INPUT_FILE%) do set "randline=%%a" & goto continue
:continue
echo Line #%randnum% is:
echo/!randline!
就像StackOverflow 中已经提到的一样%RANDOM%
,它扩展为 0 到 32767 之间的随机数。
您可以使用此机制生成随机行号。但是,要使其成为有效的行号,您必须通过输入文本文件中的行数对其进行规范化。
这是一个简单的脚本,展示了如何做到这一点:
@echo off
setlocal enabledelayedexpansion
set INPUT_FILE="test.txt"
:: # Count the number of lines in the text file and generate a random number
set lines=0
for /f "usebackq" %%a in (%INPUT_FILE%) do set /a lines+=1
echo %RANDOM% >nul
set /a randnum=%RANDOM% * !lines! / 32768 + 1
:: # Extract the line from the file
set lines=0
for /f "usebackq tokens=*" %%a in (%INPUT_FILE%) do (
set /a lines+=1
if !lines!==!randnum! set randline=%%a
)
echo Line #!randnum! is:
echo.!randline!
这是另一种方法。它从命令行读取文件名并使用FOR /L
循环来获取计算的行号:
@ECHO OFF
FOR /F "" %%I IN ('FIND /C /V "" ^<%1') DO SET /A lines=%%I
SET /A skip=%RANDOM%%%lines
<%1 (
FOR /L %%I IN (1,1,%skip%) DO (
SET /P line=
)
SET line=
SET /P line=
)
ECHO(%line%
循环只是获取文件中的FOR /F
行数(该方法是从@Aacini 的答案中借用的)。
然后一个相当简单的公式计算文件中要跳过的行数。
接下来,读取文件。循环仅使用一条指令FOR /L
消耗指定数量的行。SET /P
在循环之后,另一个SET /P
命令读取最终 ECHO 的行。
上面的实现只是为了展示基本思想。这并非没有问题,但其中一些问题很容易解决:
没有测试是否确实提供了参数。如果不存在,脚本将中断。您可以在脚本开头添加必要的检查,如下所示:
IF "%~1"=="" GOTO :EOF
如果没有参数,此命令通过将控件发送到脚本末尾 (
GOTO :EOF
) 来终止脚本。指定的文件可能不存在。同样,您可以在开始时进行测试,在验证是否提供了参数之后,在必要时终止脚本:
IF NOT EXIST %1 GOTO :EOF
如果文件为空,则
lines
will be0
和使用它的后续表达式将遇到除以零错误。因此,您还需要测试生成的行数(如果行数确实为 0,则阻止脚本进一步运行)。您可以通过在FOR /F
循环之后添加以下行来做到这一点:IF %lines%==0 GOTO :EOF
就像我说的,这个公式有点简单。它不会产生大于 32767 的数字,这是
%RANDOM%
. 这对您来说可能已经足够了,但如果不是,您可以使用以下两个调用将范围扩展到 2 30 -1 :%RANDOM%
SET /A skip=(%RANDOM%*32768+%RANDOM%)%%lines
因此,这里又是相同的脚本,经过修改以解决上述问题:
@ECHO OFF
IF "%~1"=="" GOTO :EOF
IF NOT EXIST %1 GOTO :EOF
FOR /F "" %%I IN ('FIND /C /V "" ^<%1') DO SET /A lines=%%I
IF %lines%==0 GOTO :EOF
SET /A skip=(%RANDOM%*32768+%RANDOM%)%%lines
<%1 (
FOR /L %%I IN (1,1,%skip%) DO (
SET /P line=
)
SET line=
SET /P line=
)
ECHO(%line%
另一个注意事项是,如果您愿意,可以添加消息来解释脚本提前终止的原因。基本上,无论你想在哪里添加消息,你只需要替换单个
GOTO :EOF
和
(ECHO your message & GOTO :EOF)
例如:
IF NOT EXIST %1 (ECHO Error! File not found & GOTO :EOF)