简体   繁体   中英

Windows Command Prompt print text file with delay

I have no experience with command prompt whatsoever, but I'd like to make a batch script (for fun and learn) that would print a text file from a given location, line by line , with a 1 second delay .
I would also want it to be able to pause/unpause when I press a designated key (ex: space ) and feed me an extra line (on top of those already programmed to run) when I press another key (ex: enter ).

I know I can add a 1 second delay by pinging localhost ping -n 5 127.0.0.1 > nul
And I know I can see the content of a text file using more text.txt , but I don't know how to iterate through an entire text file until EOF is met and I don't know how to pause/resume and feed extra line.

Hope it doesn't sound stupid or out of scope in this context, but it's just something that interests me right know and I know a lot people here have the knowledge to do this.

1) If you have experience in programming, you will know using a for loop is the most common way to do things one by one, eg line by line .

2) You can simply use ping localhost -n 2 >nul for 1 second delay, the 2 in the ping is not indicating 2 seconds, but 1 second instead. (I have no idea about that, just get used to it)

3) You can't pause/unpause when cmd is pinging, I mean there's no way to force the program to pause/unpause because the delay process is executed in just a line of code! Or you can magically add some code into it like ping localhost -n 2 pause while(KeyDown(SPACE)) >nul (just kidding :) )

4) Extra lines? Hmm... Remember batch is not a powerful language so... Yeah


Here is a simple code to print text line by line each second in a .txt file

for /f %%a in (your_text.txt) do (
    echo %%a
    ping localhost -n 2 >nul
)

You could do it synchronously with choice /t 1 (for a 1-second timeout) and some key other than Spacebar . Perhaps P for Pause?

@echo off
setlocal

set "textfile=notes.txt"

echo Hit P to pause / resume, Q to quit.
echo;

for /f "tokens=1* delims=:" %%I in ('findstr /n "^" "%textfile%"') do (
    echo(%%J
    choice /t 1 /c €pq /d € >NUL
    if errorlevel 3 exit /b 0
    if errorlevel 2 (
        pause >NUL
        ping -n 1 -w 750 169.254.1.1 >NUL
    )
)

exit /b 0

Unfortunately, choice only allows az, AZ, 0-9, and extended characters 128-254. There's no way to make it listen for Enter or Space . And choice is the only Windows command of which I'm aware that'll accept a single keypress and do something meaningful based on which key was pressed.

I think you'll have to use some sort of compiled language (or possibly PowerShell with a .NET class?) to listen for keypress events on the console. You could probably do it in JavaScript, but you'd have to display your output in a web browser or HTA window.

A "scrolling editor"? It is a crazy idea, isn't it? I LIKE IT! ;-) I adopted your project and add some points...

@echo off

rem ScrollEditor.bat: "dynamic" very simple line editor
rem Antonio Perez Ayala aka Aacini

if "%~1" neq "" if "%~1" neq "/?" goto begin

echo ScrollEditor.bat filename.ext
echo/
echo File lines will be continually scrolling, one per second.
echo/
echo You may pause the scroll via P key. In the "paused" state, the last displayed
echo line is named "current line", and the following commands are active:
echo/
echo    #L     Return/advance the listing to line #; continue the scroll from there.
echo    [#]D   Delete [from previous line # up to] current line.
echo    I      Insert lines after current line; end insert with *two* empty lines.
echo    P      End "paused" state; continue the scroll from current line on.
echo    E      End edit and save file, keep original file with .bak extension.
echo    Q      Quit edit, not save file.
goto :EOF

:begin
if not exist %1 echo File not found & goto :EOF

rem Load file lines into "line" array
set /P "=Loading file... " < NUL
setlocal DisableDelayedExpansion
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %1') do (
   set "line[%%a]=%%b"
   set "lastLine=%%a"
)
echo last line: %lastLine%
echo To pause scrolling, press: P
echo/
setlocal EnableDelayedExpansion

set "validCommands=LDIPEQ"
set currentLine=1
:command-P  End "paused" state
:ScrollLine
   if %currentLine% gtr %lastLine% (
      set "currentLine=%lastLine%"
      echo  EOF
      goto GetCommand
   )
   set "num=   %currentLine%"
   echo %num:~-4%: !line[%currentLine%]!
   set /A currentLine+=1
   choice /C PC /N /T 1 /D C >NUL
if errorlevel 2 goto ScrollLine

rem Enter paused state
set /A currentLine-=1
:GetCommand
echo/
set /P "command=Command [#L,#D,I,P,E,Q]? "
set "letter=%command:~-1%"
if "!validCommands:%letter%=!" equ "%validCommands%" goto GetCommand
goto command-%letter%

:command-L  Go to line #; continue scrolling
set "currentLine=%command:~0,-1%"
goto ScrollLine


:command-D  Delete from line # to current line
set "prevLine=%command:~0,-1%"
if not defined prevLine set "prevLine=%currentLine%"

rem Move lines after last deleted one into deleted lines
set /A currentLine+=1, newCurrent=prevLine-1, lines=currentLine-prevLine
for /L %%j in (%currentLine%,1,%lastLine%) do (
   set "line[!prevLine!]=!line[%%j]!"
   set /A prevLine+=1
)
set /A currentLine=newCurrent, lastLine=prevLine-1
if %currentLine% equ 0 set "currentLine=1"
echo %lines% line(s) deleted (current=%currentLine%, last=%lastLine%)
goto GetCommand


:command-I  Insert lines after current one
echo End insert with *two* empty lines
echo/

rem Read new lines into "ins" array
set "newLine=%currentLine%"
:insertLine
   set "line="
   set /A newLine+=1
   set "num=  %newLine%"
   set /P "line=+%num:~-3%: "
   set "ins[%newLine%]=!line!"
   rem The most complex part: end in two empty lines...
   if not defined line (
      set /A newLine+=1
      set "num=  !newLine!"
      set /P "line=+!num:~-3!: "
      if defined line (
         set "ins[!newLine!]=!line!"
      ) else (
         set /A newLine-=2
      )
   )
if defined line goto insertLine

rem Move old lines to new place to make room for new lines
set /A lines=newLine-currentLine, currentLine+=1, newLast=lastLine+lines
for /L %%j in (%lastLine%,-1,%currentLine%) do (
   set "line[!newLast!]=!line[%%j]!"
   set /A newLast-=1
)

rem Insert new lines in old place
for /L %%j in (%currentLine%,1,%newLine%) do set "line[%%j]=!ins[%%j]!"
set /A lastLine+=lines, currentLine=newLine
echo %lines% line(s) inserted (current=%currentLine%, last=%lastLine%)
goto GetCommand


:command-E  End edit, save file
echo Saving file...
move /Y %1 "%~N1.bak"
(for /L %%i in (1,1,%lastLine%) do echo(!line[%%i]!) > %1

:command-Q  Quit edit
echo End edit

This program have multiple problems: don't check for valid input in commands, may have problems with special Batch characters and if the first character of a line is a colon, eliminate it. However, it is a good starting point for this project!

Perhaps you may be interested in this similar project .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM