Skip to main content

How to Wrap Text at a Specific Column Width in Batch Script

Raw text from logs or long summaries can often exceed the width of the terminal, forcing the user to scroll horizontally or causing the text to break in the middle of a word when the console auto-wraps. Text Wrapping ensures that your reports stay within a clean vertical column (e.g., 60 characters wide) by inserting line breaks at the appropriate places, ideally between words.

In this guide, we will demonstrate how to implement a text wrapper using Batch and a PowerShell bridge.

The Strategy: The Intelligent Word Wrap

Simple truncation is easy, but it results in words being sliced in half (e.g., "Initializing" becomes "Initia" and "lizing"). A professional wrapper identifies the last space before the column limit and breaks the line there.

Method 1: The Native Batch Word Wrapper

This method iterates through the string and finds the last space within the column limit to produce clean word-boundary breaks. It is best suited for short messages or single-string wrapping.

Implementation Script

@echo off
setlocal enabledelayedexpansion

set "longText=This is a very long string of text that we want to wrap so that it does not exceed a specific width in our console window output."
set "limit=40"

echo --- Word-wrapped output (%limit% columns)^ ---
echo.

:wrapLoop
:: If remaining text is empty, we are done
if not defined longText goto :wrapDone

:: Check if remaining text fits within the limit
call :strlen longText textLen
if !textLen! leq !limit! (
echo(!longText!
goto :wrapDone
)

:: Extract a chunk up to the column limit
set "chunk=!longText:~0,%limit%!"

:: Find the last space in the chunk for a clean word break
set "breakPos="
for /L %%i in (0,1,!limit!) do (
if "!chunk:~%%i,1!"==" " set "breakPos=%%i"
)

:: If no space was found, force-break at the limit
if not defined breakPos (
echo(!chunk!
set "longText=!longText:~%limit%!"
goto :wrapLoop
)

:: Output text up to the last space
set "wrapped=!longText:~0,%breakPos%!"
echo(!wrapped!

:: Remove the wrapped portion plus the space itself
set /a "remaining=breakPos + 1"
set "longText=!longText:~%remaining%!"
goto :wrapLoop

:wrapDone
echo.
pause
exit /b 0

:strlen
:: %~1 = variable NAME, %~2 = output variable for length
setlocal enabledelayedexpansion
set "s=!%~1!"
set "n=0"
:strlenLoop
if defined s (
set "s=!s:~1!"
set /a "n+=1"
goto :strlenLoop
)
endlocal & set "%~2=%n%"
exit /b 0
warning

The native Batch method is significantly slower than PowerShell for large text blocks because it processes each character individually in a goto loop. Use this method for short strings such as status messages or help text. For wrapping entire files, use Method 2 instead.

tip

The script searches backward through the chunk to find the last space character. If a single word exceeds the column limit (such as a long URL), no space will be found, and the script falls back to a hard break at the limit. This prevents an infinite loop that would occur if the script refused to output a line without a word boundary.

PowerShell has robust string manipulation capabilities for handling word boundaries. This method processes entire files and produces correctly wrapped output.

Implementation Script

@echo off
setlocal

set "Source=LongReport.txt"
set "Dest=WrappedReport.txt"
set "Limit=60"

:: Verify source file exists
if not exist "%Source%" (
echo [ERROR] Source file "%Source%" not found.
pause
exit /b 1
)

echo Wrapping "%Source%" at %Limit% columns...

:: Process each line independently to preserve paragraph breaks
:: The regex matches up to N characters ending at a word boundary
powershell -NoProfile -Command ^
"$limit = %Limit%; " ^
"$lines = Get-Content -Path '%Source%'; " ^
"$result = foreach ($line in $lines) { " ^
" if ($line.Length -le $limit) { $line } " ^
" else { " ^
" $remaining = $line; " ^
" while ($remaining.Length -gt $limit) { " ^
" $breakPos = $remaining.LastIndexOf(' ', $limit); " ^
" if ($breakPos -le 0) { $breakPos = $limit } " ^
" $remaining.Substring(0, $breakPos); " ^
" $remaining = $remaining.Substring($breakPos).TrimStart(); " ^
" } " ^
" if ($remaining) { $remaining } " ^
" } " ^
"}; " ^
"$result | Set-Content -Path '%Dest%' -Encoding UTF8"

if %errorlevel% equ 0 (
echo [SUCCESS] Wrapped output saved to "%Dest%".
) else (
echo [ERROR] Wrapping failed.
pause
exit /b 1
)
pause
exit /b 0
info

The PowerShell script processes each line from the source file independently. Empty lines (paragraph separators) pass through unchanged, preserving the original paragraph structure. Lines shorter than the limit are also passed through without modification, so only lines that actually exceed the column width are wrapped.

Why Wrap Your Text?

  1. Readability: The human eye scans text more comfortably when the line length is between 50 and 75 characters.
  2. Printing Compatibility: If your script generates reports that might be printed, wrapping at 80 characters ensures they fit on standard A4/Letter paper without being cut off.
  3. UI Polish: If you are building a box around your text output, you must wrap your text so it stays inside the frame.

Best Practices

  1. Handle Tabs First: Before wrapping, convert all tabs to spaces. A single tab character occupies one position in the string but renders at a variable width in the console, which throws off column calculations.
  2. Preserve Paragraphs: Ensure your wrapper does not collapse empty lines (paragraph separators) while processing. Method 2 handles this by processing each line independently rather than joining the entire file into a single string.
  3. Long Words: Always include a fallback for words that exceed the column limit (such as long URLs or file paths). Without a hard-break fallback, the wrapping loop will never find a space and will loop infinitely.
  4. Verify Source File: Always check that the input file exists before processing. A missing file will cause PowerShell to throw an exception or produce empty output.
  5. Encoding: Include -Encoding UTF8 in the PowerShell Set-Content command to prevent non-ASCII characters from being corrupted by the default ANSI encoding in PowerShell 5.1.

Conclusion

Text wrapping is a foundational element of console output formatting. It moves your script's output from raw, unformatted data to clean, readable information. By using either a native loop for short alerts or a robust PowerShell bridge for large files, you ensure that your documentation and reports are always easy to digest, regardless of the user's terminal size.