テキスト ファイルからテキストのランダムな行を選択し、それを使用する変数に設定するにはどうすればよいでしょうか?
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!
ここ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
。ループに続いて、もう 1 つのSET /P
コマンドが、最終的に ECHO される行を読み取ります。
上記の実装は、基本的な考え方を示すためのものです。問題がないわけではありませんが、いくつかは簡単に解決できます。
パラメータが実際に指定されているかどうかのテストはありません。存在しない場合、スクリプトが壊れます。次のように、スクリプトの先頭に必要なチェックを追加できます。
IF "%~1"=="" GOTO :EOF
パラメーターがない場合、このコマンドは、制御をスクリプトの最後に送信してスクリプトを終了します (
GOTO :EOF
)。指定されたファイルが存在しない可能性があります。繰り返しますが、必要に応じてスクリプトを終了するために、パラメーターが指定されていることを確認した直後に、最初にそれをテストできます。
IF NOT EXIST %1 GOTO :EOF
ファイルが空の場合は
lines
、0
それを使用する後続の式でゼロ除算エラーが発生します。したがって、結果の行数もテストする必要があります (カウントが実際に 0 の場合は、スクリプトがそれ以上実行されないようにします)。FOR /F
これを行うには、ループの直後に次の行を追加します。IF %lines%==0 GOTO :EOF
私が言ったように、式はいくぶん単純化されています。の制限である 32767 を超える数値は生成されません
%RANDOM%
。これで十分かもしれませんが、そうでない場合は、次のように2 つの呼び出しを使用して範囲を 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%
もう 1 つの注意点は、必要に応じて、スクリプトが途中で終了する理由を説明するメッセージを追加できることです。基本的に、メッセージを追加したい場所はどこでも、単一のメッセージを置き換えるだけです。
GOTO :EOF
と
(ECHO your message & GOTO :EOF)
例えば:
IF NOT EXIST %1 (ECHO Error! File not found & GOTO :EOF)