使用批处理的随机文本行

时间:2012-11-12 11:46:00

标签: text random batch-file line

如何从文本文件中选择随机文本行并将其设置为要使用的变量?

3 个答案:

答案 0 :(得分:3)

下面的批处理程序是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!

答案 1 :(得分:2)

就像在StackOverflow中已经提到here一样,%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!

答案 2 :(得分:1)

这是另一种方法。它从命令行读取文件名,并使用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's answer)。

一个相当简单的公式然后计算文件中要跳过的行数。

接下来,读取文件。 FOR /L循环仅使用SET /P指令消耗指定数量的行。循环之后,再一个SET /P命令读取最终被ECHOed的行。

以上实现只是为了展示基本思想。这不是没有问题,但有些问题很容易解决:

  1. 没有测试参数是否确实提供。如果不存在,脚本将会中断。您可以在脚本的开头添加必要的检查,如下所示:

    IF "%~1"=="" GOTO :EOF
    

    如果没有参数,则此命令通过将控件发送到脚本末尾(GOTO :EOF)来终止脚本。

  2. 指定的文件可能不存在。同样,您可以在开始时,在验证参数提供之后测试,以便在必要时终止脚本:

    IF NOT EXIST %1 GOTO :EOF
    
  3. 如果文件为空,lines将为0,使用它的后续表达式将运行为零除错误。因此,您还需要测试生成的行数(如果计数确实为0,则阻止脚本进一步运行)。您可以通过在FOR /F循环之后添加以下行来执行此操作:

    IF %lines%==0 GOTO :EOF
    
  4. 就像我说的那样,公式有点简单。它不会产生大于32767的数字,这是%RANDOM%的限制。这对你来说可能已经足够了,但如果不是,你可以使用两个 %RANDOM%调用将范围扩展到2 30 -1,如下所示:

    SET /A skip=(%RANDOM%*32768+%RANDOM%)%%lines
    
  5. 所以,这里再次使用相同的脚本,修改以解决上述问题:

    @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)