Windows cmd: echo without new line but with CR

2019-02-15 05:14发布

I would like to write on the same line inside a loop in a windows batch file. For example:

setlocal EnableDelayedExpansion
set file_number=0
for %%f in (*) do (
  set /a file_number+=1
  echo working on file number !file_number!
  something.exe %%f
)
setlocal DisableDelayedExpansion

This will result in:

echo working on file number 1

echo working on file number 2

echo working on file number 3

. . .

I would like all of them to be on the same line. I found a hack to remove the new line (e.g. here: Windows batch: echo without new line), but this will produce one long line.

Thanks!

2条回答
做自己的国王
2楼-- · 2019-02-15 05:47
@echo off
    setlocal enableextensions enabledelayedexpansion

    for /f %%a in ('copy "%~f0" nul /z') do set "CR=%%a"

    set "count=0"
    for %%a in (*) do (
        set /a "count+=1"
        <nul set /p ".=working on file !count! !CR!"
    )

The first for command executes a copy operation that leaves a carriage return character inside the variable.

Now, in the file loop, each line is echoed using a <nul set /p that will output the prompt string without a line feed and without waiting for the input (we are reading from nul). But inside the data echoed, we include the carriage return previously obtained.

BUT for it to work, the CR variable needs to be echoed with delayed expansion. Otherwise it will not work.

If for some reason you need to disable delayed expansion, this can be done without the CR variable using the for command replaceable parameter

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f %%a in ('copy "%~f0" nul /z') do (
        for /l %%b in (0 1 1000) do (
            <nul set /p ".=This is the line %%b%%a"
        )
    )
查看更多
ら.Afraid
3楼-- · 2019-02-15 05:47

Thanks to the answer of MC ND I have a created a subroutine, echocr, that you can call without delayed expansion, that will echo a string with only a carriage return, and no newline. (The spaces after %input% are adjusted to cover all previous messages).

You can use it to overwrite a line as shown in the modified code:

@echo off

call :echocr "good morning"
PING -n 2 127.0.0.1>nul
call :echocr "good afternoon"
PING -n 2 127.0.0.1>nul
call :echocr "bye now"
PING -n 2 127.0.0.1>nul
pause

:echocr

:: (echo string with carriage return, no line feed)

for /F "tokens=1 delims=# " %%a in (
'"prompt #$H# & echo on & for %%b in (1) do rem"'
) do set "backspace=%%a"

set input=%~1
set "spaces40=                                       "
set "spaces120=%spaces40%%spaces40%%spaces40%
for /f %%a in ('copy "%~f0" nul /z') do (  
    set /p ".=*%backspace%%spaces120%%%a" <nul      
    set /p ".=*%backspace%%input%%%a" <nul
)    
exit /b
查看更多
登录 后发表回答