Skip to main content

How to Get a Random Line from a Text File in Batch Script

A common feature in applications and scripts is the ability to display a random piece of information, such as a "tip of the day," a random quote, or selecting a random server from a list. To do this, you need a way to read a text file and select one of its lines at random. While Windows Batch has no direct, single command to do this, it is a classic scripting problem that can be solved with native commands.

This guide will teach you the "pure-batch" method, a three-step process that involves counting the lines, generating a random number, and then retrieving the specific line. More importantly, it will demonstrate the vastly simpler and more efficient modern approach using a PowerShell one-liner, which is the recommended method for its performance and reliability.

The Challenge: No Native Get-RandomLine Command

The cmd.exe interpreter cannot simply pick a random line. The process must be broken down into logical steps that batch can perform:

  1. Determine the total number of lines in the file to set the upper bound for our random number.
  2. Generate a random number within that range.
  3. Read the file again, skipping lines until we arrive at our chosen random line.

This is a multi-step, multi-pass process.

The Core Method (Pure Batch): The "Count and Skip" Method

This is the traditional, self-contained batch solution. It is a great example of advanced scripting but is not very efficient.

The logic:

  1. Count Lines: Use find /c /v "" to get the total number of lines in the file.
  2. Generate Random Number: Use %RANDOM% and a simple formula to scale it to a random line number between 1 and the total.
  3. Skip and Read: Use a FOR /F loop with the skip= option to read the file, skipping the required number of lines to land on our target.

For any modern Windows system, a PowerShell one-liner is a far better solution. It reads the file only once and is extremely simple and fast.

Syntax: powershell -Command "Get-Content 'filename.txt' | Get-Random"

  • Get-Content: Reads the entire file into a collection of lines.
  • |: The pipe sends this collection to the next command.
  • Get-Random: This cmdlet is designed to pick one or more items at random from a collection.

Basic Example: A "Quote of the Day" Script

Let's select a random line from a file named quotes.txt.

The only way to do great work is to love what you do.
The best time to plant a tree was 20 years ago. The second best time is now.
Your time is limited, so don't waste it living someone else's life.

Method 1: Pure Batch Script

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "FileName=quotes.txt"

REM --- Step 1: Count the lines ---
FOR /F %%C IN ('FIND /C /V "" ^< "%FileName%"') DO SET "TotalLines=%%C"

REM --- Step 2: Generate a random line number ---
SET /A "RandomLine=%RANDOM% * %TotalLines% / 32768 + 1"
SET /A "LinesToSkip=%RandomLine% - 1"

REM --- Step 3: Skip lines and get the target line ---
IF %LinesToSkip% LSS 0 SET "LinesToSkip=0"
FOR /F "skip=%LinesToSkip% delims=" %%L IN ('findstr /n "^" "%FileName%"') DO (
SET "RandomQuote=%%L"
SET "RandomQuote=!RandomQuote:*:=!"
GOTO :QuoteFound
)

:QuoteFound
ECHO Batch Method Quote: !RandomQuote!
ENDLOCAL

Method 2: PowerShell Script

@ECHO OFF
SET "FileName=quotes.txt"
FOR /F "delims=" %%Q IN ('powershell -Command "Get-Content '%FileName%' | Get-Random"') DO (
SET "RandomQuote=%%Q"
)
ECHO PowerShell Method Quote: %RandomQuote%

How the Pure Batch Script Works (A Step-by-Step Breakdown)

  • Line Count: FIND /C /V "" is the standard, robust way to count all lines in a file, including empty ones.
  • Random Number: SET /A "RandomLine=%RANDOM% * %TotalLines% / 32768 + 1" is the standard formula to scale the output of %RANDOM% (0-32767) to a range of 1 to TotalLines.
  • Skipping: FOR /F "skip=%LinesToSkip% ..." is the key to getting the line.
  • findstr /n "^": We pipe the file through this to handle empty lines. It prefixes each line with its number (e.g., 3:content), which prevents FOR /F from skipping blank lines.
  • !RandomQuote:*:=!: This removes the 3: prefix added by findstr, leaving us with the clean, original line.
  • GOTO :QuoteFound: This is an essential optimization. Once we have our line, we immediately exit the loop.

Common Pitfalls and How to Solve Them

Problem: The Script is Very Slow on Large Files

The pure-batch method must read the file twice: once to count all the lines, and a second time to skip to the random line. For a file with millions of lines, this is extremely inefficient.

Solution: Use the PowerShell method. Get-Content | Get-Random reads the file only once. For very large files, it can even be optimized further in PowerShell to not load the whole file into memory, making it the clear winner for performance.

Problem: The Random Line is an Empty Line

If your text file contains blank lines, it's possible for the script to correctly select one of them as the "random line."

Solution: This is not a bug, but it might be undesirable.

  • Pure Batch: This is difficult to solve. You would have to re-run the entire count/random/skip process in a loop until a non-empty line was found.
  • PowerShell (Recommended): This is very easy to solve. You can filter out the empty lines before picking one.
    powershell -Command "Get-Content 'file.txt' | Where-Object { $_.Trim() -ne '' } | Get-Random"

Practical Example: A "Tip of the Day" Logon Script

This script is designed to be run when a user logs in. It uses the robust PowerShell method to display a random tip from a central file.

@ECHO OFF
SETLOCAL
SET "TipFile=\\FileServer\Shared\corp_tips.txt"

ECHO --- Tip of the Day ---
ECHO.

IF NOT EXIST "%TipFile%" (
ECHO Have a great day!
GOTO :End
)

FOR /F "delims=" %%T IN (
'powershell -NoProfile -Command "Get-Content '%TipFile%' | Where-Object { $_.Trim() -ne '' } | Get-Random"'
) DO (
ECHO %%T
)

:End
ECHO.
PAUSE
ENDLOCAL

Conclusion

While you can get a random line from a file using a pure batch script, it's a complex and inefficient process that is a great showcase of the language's limitations.

  • The pure-batch "Count and Skip" method is a functional native solution but is very slow on large files and clumsy to write.
  • The PowerShell Get-Content | Get-Random method is the overwhelmingly recommended best practice. It is faster, more reliable, more concise, and easily adaptable to handle edge cases like empty lines.