Skip to main content

How to Display Dynamic Status Updates on the Same Line in Batch Script

When running a script that performs hundreds of small operations, such as renaming files, hashing contents, or pinging servers, your console can quickly become cluttered with thousands of lines of log data. Dynamic Status Updates allow you to update a single line on the screen repeatedly (e.g., Processing file 50/100...), keeping the interface clean and professional.

In this guide, we will demonstrate how to use ANSI escape codes to overwrite the current line in real-time.

The Logic: Cursor Repositioning

To update text on the same line, we need two operations:

  1. Move the cursor back to the beginning of the current line.
  2. Clear any remaining characters from the previous output so shorter text doesn't leave artifacts.

ANSI escape codes provide both of these capabilities.

Method 1: The Modern ANSI Method (Windows 10/11)

On modern Windows systems, we use the ANSI code ESC[1G (Move Cursor to Column 1) combined with ESC[K (Erase to End of Line) to cleanly overwrite the current line.

@echo off
setlocal EnableDelayedExpansion

:: Capture ESC character (ASCII 27)
for /F %%A in ('echo prompt $E ^| cmd') do set "ESC=%%A"

if not defined ESC (
echo [ERROR] ANSI escape not available.
pause
exit /b 1
)

set "totalItems=100"

echo Initializing bulk operation...
echo.

:: Loop to simulate processing
for /L %%i in (1,1,%totalItems%) do (
set /a pct=%%i*100/totalItems

:: Use delayed expansion for variables inside loop
<nul set /p "=!ESC![1G!ESC![KProcessing: %%i/!totalItems! items (!pct!%%)..."

:: Simulate work (~50ms delay)
ping -n 1 -w 50 127.0.0.1 >nul
)

:: Clear the progress line and print final status
<nul set /p "=!ESC![1G!ESC![K"
echo [DONE] Operation finished successfully.
echo.

endlocal
pause

Why we use ESC[K (Erase in Line):

If your previous output is Processing: 100/100 items... (30 characters) and the next update is Done! (5 characters), the terminal would show Done!sing: 100/100 items..., the shorter text only overwrites the first 5 characters, leaving the rest of the old text visible. The ESC[K code erases everything from the cursor position to the end of the line, preventing these artifacts.

Method 2: The Relative "Backtrack" Method

If you want to update only a specific portion of a line rather than the entire line, you can use the relative cursor movement code ESC[nD (move cursor left by n positions) to back up and overwrite just the part that changed.

@echo off
setlocal EnableDelayedExpansion

:: Capture ESC character
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"

if not defined ESC (
echo [ERROR] Could not generate ANSI escape character.
pause
exit /b 1
)

:: Print initial status
<nul set /p "=Status: [WAIT]"

:: Simulate work
timeout /t 2 /nobreak >nul

:: Move cursor back 6 chars, overwrite, and clear remainder
<nul set /p "=!ESC![6D[DONE]!ESC![K"

echo.

endlocal
pause
info

When to use each method:

  • ESC[1G + ESC[K (Method 1): Best for replacing the entire line content. The cursor jumps to column 1 and the erase command cleans up any leftover characters. Use this for progress counters, status messages, and any line that changes completely on each update.
  • ESC[nD (Method 2): Best for updating a small portion at the end of a line while keeping the beginning intact. You must know the exact character count of the text being replaced, and the new text should be the same length or followed by ESC[K to clean up.

Practical Scenarios for Dynamic Updates

  1. File Synchronization: Instead of listing every file copied, show [Copying] 450 MB / 1200 MB.
  2. Server Monitoring: Show the current response time of a server updating every second on a single line.
  3. Build Progress: Display the current compilation step without flooding the terminal with hundreds of log lines.
  4. Hardware Sensors: Display CPU temperature or RAM usage in a compact "live" dashboard.

Best Practices

  1. Avoid Excessive Screen Flicker: If you update the screen too fast (e.g., 1000 times per second), the line will flicker. Aim for a maximum of 10 to 20 updates per second for smooth visual feedback.
  2. End with a New Line: Once your dynamic loop finishes, always use echo. to move the cursor to the next line. If you don't, the next echo command or the command prompt itself will overwrite your final status update.
  3. Always Use ESC[K: Prefer the Erase in Line code over manual space padding. It handles any length difference automatically and produces cleaner output.

Conclusion

Dynamic status updates turn a "scrolling log" into a "dashboard interface." By mastering the ESC[1G and ESC[K escape sequences, you can create Batch scripts that provide real-time, high-density information without overwhelming the user's terminal. This clean approach to user feedback is a hallmark of professional automation tools.