How to replace last line in Windows batch code? - batch-file

I am trying to make a text-based game, and when the user enters something, I want the computer's character to have some kind of thinking animation.
I've come up with this: [. ] [.. ] [...]
Only problem is, I want it all to be on one line, so it's like an actual animation. I've successfully recreated this without removed the text already echo'd, but it requires that you cls, then send all that was on the screen before, three times. Obviously this takes too much space and is pretty inefficient.
I found a code that changes the last like without clearing all that was before it,
#echo off
echo This won't disappear!
setlocal EnableDelayedExpansion
for /f %%a in ('copy /Z "%~f0" nul') do set "CR=%%a"
for /L %%n in (5 -1 1) do (
<nul set /P "=This window will close in %%n seconds!CR!"
ping -n 2 localhost > nul
)
It counts down without erasing the echo before, but I do not understand how to adapt it to add periods to my string... Does anyone know a way to do this? Thanks!

You were almost there with the code you found; you just need to use your own text instead of somebody else's.
for /L %%A in (1,1,3) do (
set /p "=."<nul
ping -n 2 localhost >nul
)
If you want to put the periods inside of brackets, you can use this:
for /f %%A in ('"prompt $H &echo on &for %%B in (1) do rem"') do set BS=%%A
set /p "=[ ]"<nul
ping -n 2 localhost >nul
set /p "=%BS%%BS%%BS%%BS%. ]"<nul
ping -n 2 localhost >nul
set /p "=%BS%%BS%%BS%. ]"<nul
ping -n 2 localhost >nul
set /p "=%BS%%BS%.]"<nul
ping -n 2 localhost >nul

Related

Splitting ip and port in ip:port format using batch

For the program I am currently working on I am taking a value, which is a proxy in ip:port format, I need to be able to split the ip and port to different variables so that a different program that needs ip and port separate will be able to work. The program is basically an automated ip/proxy switcher for minecraft, just for in game reasons, I have all the code working except for the part that actually changed the proxy. I am not getting any error message, only that I don't actually know what code to write. Anyways, here is my code.
#echo off
color b
title minecraft proxy switcher
set nLine=0
echo input full path to text file containing proxies
set /P "filepath=>"
echo end >> %filepath%
:top
cls
set /A nLine=%nLine%+1
echo now at proxy number %nLine%
CALL :ReadNthLine "%filepath%" %nLine%
PAUSE >NUL & goto:top
GOTO :EOF
::***************************************************************************************
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO set http_proxy=%%B
goto finish
::***************************************************************************************
:finish
if %http_proxy%==end (
cls
echo all proxies have been used
echo will return to top of list in 5 seconds
TIMEOUT /T 5 /NOBREAK
set nLine=0
goto top
)
java -DsocksProxyHost=ip -DsocksProxyPort=port -Xmx800m -jar MinecraftLauncher.exe
echo New ip is %http_proxy%
echo waiting for user input
echo press any key for a new ip
pause
goto top
Any help is greatly appreciated, also if you notice something else that's badly written or incorrect in my code please tell me.
split the string with a for, using proper tokens and delimiters:
set "line=192.168.1.1:8080"
for /f "tokens=1,2 delims=:" %%a in ("%line%") do (
set server=%%a
set port=%%b
)
echo Server %server% Port %port%
here is a basic code skeleton which processes the file line after line (your way works, but this is way easier):
#echo off
set /p "filepath=File: "
:top
set n=0
for /f "tokens=1,2 delims=:" %%a in (%filepath%) do call :process %%a %%b
timeout 5
goto :top
:process
echo trying %n%
set /a n+=1
echo host: %1
echo port: %2
pause
goto :eof

Batch file issue not solved

I've tried to create an invisible countdown.
For example, the script starts the countdown, but in the meantime the script runs like an MMORPG. When you are entering an instance dungeon, it starts the countdown and you can walk etc. But when I do it with PING -n 6 127.0.0.1 //Delay the script for 5 seconds. I want the PING to run in the background and meanwhile the script goes on. I've got a response from Stephan but his code didn't work :(
Stephan's Code:
#echo off
setlocal enabledelayedexpansion
REM create a CarriageReturn:
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
for /L %%i in (5,-1,0) do (
<nul set /p =King Albireo is spawning in %%i seconds...!CR!
ping -n 2 127.0.01 >nul
)
goto Main
:Main
#title Example: Countdown
cls
echo It works
pause
Can someone make this script so it is running in the background and meanwhile the script goes on.
I know I used the same words over and over just to make sure everyone is getting what I am trying to say.
BTW thanks Stephan for the code.
You can try with
start "" /b cmd /q /v /e /c"(for /l %%a in (5 -1 1) do (echo respawn in %%a seconds&>nul ping -n 2 ""))&echo RESPAWN"

Set /p in a loop?

This is probably impossible, but I have a loop that displays a animated logo by using TYPE to type logo_(framenumber).txt and the framenumber is determined by a loop:
:s
if %m%==379 set m=0
cls
TYPE Logo_%m%.txt
set /a m=%m%+1
goto s
I wanted to be able to use a set /p option and without disturbing/stopping the loop so the animation plays while a user is typing in the set /p input. I think there is a way to do it with FOR but I'm not sure how. Any ideas? Thanks.
Although this topic is somewhat old, I just discovered it. This is a pure Batch file solution that works pretty well:
EDIT: I slightly modified the code in order to made it simpler.
#echo off
setlocal EnableDelayedExpansion
if "%1" equ "Animate" goto %1
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"
cd . > input.txt
start "" /B "%~F0" Animate
set "input="
:nextKey
set "key="
for /F "delims=" %%K in ('xcopy /W "%~F0" "%~F0" 2^>NUL') do if not defined key set "key=%%K"
if "!key:~-1!" equ "!CR!" goto endInput
if "!key:~-1!" equ "!BS!" (
if defined input set "input=%input:~0,-1%"
) else (
set "input=%input%!key:~-1!"
)
set /P "=%input%" > input.txt < NUL
goto nextKey
:endInput
del input.txt
echo/
echo/
echo Input read: "%input%"
goto :EOF
:Animate
set "banner= Enter your name please "
set m=0
:loop
if not exist input.txt exit
set /A m=(m+1)%%51
cls
echo/
echo/ !banner:~%m%,31!
echo/
echo/
if exist input.txt (type input.txt) else exit
ping -n 1 -w 300 localhost > NUL
ping -n 1 -w 300 localhost > NUL
ping -n 1 -w 300 localhost > NUL
goto loop
In this solution the animated "logo" is replaced by a banner, but the method to display a series of files is practically the same.
EDIT: This is possible in batch. See Aacini's answer.
This is not possible with batch files. Batch commands are single-threaded. To run two things simultaneously requires two instances of cmd.exe. But the console subsystem only allows one program to own the console at a time, so if the second instance of cmd is attached to the same console, one of them must be blocked.
It is possible to do something like this with a win32 executable which uses WriteConsoleOutput to modify the characters on the console screen. If you do that, you are no longer limited to just dumping text files, but the downside is that it's a lot more work than calling type in batch.

Loading progress animation like with batch scripting

i want to make such as loading indicator just like : installation is running...
and those dots should be appear progressively and once they are three their number should be reinitialized to one dot and all happens in the same line.
for this i've tried to mix code of two small scripts : the first plays continuestly the dots
and the seconds makes a counter increase its value by echoing it in the same line.
at the end i got this code which is the closest solution for what i want to achieve but still with a problem which is that when there are already three dots, the next row which has less number of dots will overwrite its similar part from the previous one but the remaining part from the previous row will stay so at the end it looks like there are always three dots and all will looks like just a simple static echoed text..
here is the code :
#echo off
cls
setlocal EnableDelayedExpansion EnableExtensions
call :CreateCR
:spinner
set mSpinner=%mSpinner%.
if %mSpinner%'==.................................' (
set mSpinner=.
)
:: Wait one second.
ping 127.0.0.1 -n 2 >nul
set /P "=Installation Java en cours%mSpinner%!CR!" <nul
::set /p "=Installation Java en cours" <nul
::echo %mSpinner%
goto spinner
:exit
::echo(
goto :eof
:CreateCR
rem setlocal EnableDelayedExpansion EnableExtensions
set "X=."
for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094!
echo !X! > %temp%\cr.tmp
echo\>> %temp%\cr.tmp
for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do (
endlocal
set cr=%%a
goto :eof
)
goto :eof
You can capture a backspace character to a variable like this (courtesy of dbenham):
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
Then to erase your dots, simply send a number of
<NUL set /P "=%BS%"
... one %BS% for each dot you want to erase. As an alternative, you could use a spinner that spins instead of dots that grow. See this question and answer. In the answer there, insert the for /f line above to capture the backspace to %BS% at the top of the script, and replace all occurrences of ^H with %BS% in the spinner strings at the bottom.
A more simplistic approach would be the following:
#echo off
:spinner
set mSpinner=%mSpinner%.
if %mSpinner%'==....' (set mSpinner=.)
cls
echo Installation in progress%mSpinner%
ping 127.0.0.1 -n 2 >nul
goto spinner

Pinging Multiple Computers IF Statement

I'm trying to create a little batch file that checks multiple PCs read from a text file. For any PCs it finds are pingable, it writes a line in a "results" text file saying so. Here's what I've got:
#Echo off
set file=C:\logs\registercheck.txt
date /t >%file%
FOR /F %%I IN (C:\work\regnames.txt) DO (ping /n 1 %%I | ping /n 1 %%I | IF errorlevel 1 goto :nextreg | echo %%I is still on and has not been powered off! >>%file% | :nextreg)
PAUSE
So...when I run the file, I get multiple lines of "goto was unexpected at this time" and the only thing written in my output text file is the date. What am I doing wrong?
Thank you!
#Echo off
setlocal enableextensions disabledelayedexpansion
set "logFile=C:\logs\registercheck.txt"
set "inputFile=C:\work\regnames.txt"
>>"%logFile%" date /t
for /f "usebackq delims=" %%i in ("%inputFile%") do (
ping -n 1 %%i >nul 2>nul
if not errorlevel 1 (
>>"%logFile%" echo(%%i is still on and has not been powered off!
)
)
You have two errors.
The first is that to put all the commands in a single line, the separator is not the pipe character (|) but the ampersand (&)
The second is that inside the do code block of the for command, if one goto is executed, the for command is finished, independently of where the label is placed. And labels inside for code blocks usually generate errors (depends of its position).
If instead of the previous code, you want a single line loop, it can be written as
for /f "usebackq delims=" %%i in ("%inputFile%") do ( ping -n 1 %%i >nul 2>nul & if not errorlevel 1 >>"%logFile%" echo(%%i is still on and has not been powered off! )
or
for /f "usebackq delims=" %%i in ("%inputFile%") do ( ping -n 1 %%i >nul 2>nul && >>"%logFile%" echo(%%i is still on and has not been powered off! )
that makes use of the && construct. It is intended as a shortcut for the if not errorlevel 1 .... If the command at the left of the && does not raise an errorlevel, then the command on the right side is executed.
This for the batch sintax. Now the ping. There is a difference in how ping command behaves depending of the ip version. It is not the same to ping an ipv4 address than to ping an ipv6 address. If needed you can grab from here a subrotine to handle the differences.

Resources