Batch: Show last user input - batch-file

(This is my first post here, so bear with me)
Can you show the last user-input in a batch file? I'm gonna try to keep it simple here.
#echo off
:menu
echo Type 1 to proceed.
set /p example=
if "%example%" == "1" GOTO :proceed
GOTO :error
:proceed
pause
:error
cls
echo You wrote (last user input), that's not correct.
timeout 30
GOTO :menu
I know that I could replace the (last user input) with %example%, but then I'd have to make custom error messages for every category, and there are about 50 of them. It'd be easier with a last input command.
By the way, I've taught myself everything that I know about batch, so my example probably has major issues right now, but it works somehow.

You could centralize all user input into a function (user_input)
:menu1
echo Type 1 to proceed.
call :userInput example
if "%example%" == "1" GOTO :proceed
GOTO :error
:menu2
echo Type 42 to proceed.
call :userInput answer
if "%answer%" == "42" GOTO :proceed
GOTO :error
:userInput
set /p LAST_INPUT=
set "%1=%LAST_INPUT%"
exit /b
:proceed
pause
:error
cls
echo You wrote "%LAST_INPUT%", that's not correct.
timeout 30
GOTO :menu

I don't know how to do it without temp file. TO get the things written int the console you need the doskey /history (this will skip the running of the script itself):
#echo off
setlocal enableDelayedExpansion
set "last="
set "but_last="
doskey /history > log.txt
for /f "tokens=* delims=" %%# in (log.txt) do (
set "but_last=!last!"
set "last=%%#"
)
echo "%but_last%"
del /s /q log.txt >nul 2>nul

Related

batch; Save input as option for next run (livestreamer)

I created my first batch file ever a couple of weeks ago to use livestreamer more comfortably.
Basically I can either type in the name of Twitch streamer or I can start something from another plattform.
What I am trying to do is is save my input as an option for the next time.
Let's say I went to the twitch stream of "shroud". When the stream ends I would like to put shroud as an option in the beginning of the script:
:start
title twitchings
color 0a
echo Select [#] or enter Stream
echo.
echo 1. non twitch
echo 2. shroud
set /p select=?
I assume it would be easiest to store that list in a txt file and then load it upon running the batch file, but my basically non-existant knowledge in coding hinders me from creating it.
Does anyone know a quick help, I would also love to know if there is a website where I can learn this stuff without googling for hours :)
This is my updated script for those who are searching for the same issue.
#ECHO off
:start
title twitchings
color 0a
echo Select [#] or enter Stream
echo.
echo 1. non twitch
setlocal enableextensions enabledelayedexpansion
set "file=C:\Users\[...]\savedstreams.txt"
set /A i=1
for /F "usebackq delims=" %%a in ("%file%") do (
set /a i += 1
echo !i! . %%a
)
set /p select=?
set /a varCheck=%select%
if %varCheck% == %select% (goto :isnumber) else (goto :isstream)
exit /B
:isnumber
set "lineNr=%select%"
set /a lineNr-=1+1
for /f "usebackq delims=" %%a in (`more +%lineNr% savedstreams.txt`) DO (
set "stream=%%a"
goto :leave
)
:leave
set "stream=%stream:*:=%"
echo stream: %stream%
goto qual
:isstream
set "stream=%select%"
echo %stream% >>savedstreams.txt
goto qual
:TpyeInSource
echo enter URL
echo.
set /p select2=?
livestreamer %select2%
GOTO end
:qual
livestreamer http://twitch.tv/%stream% 1080p60 || livestreamer http://twitch.tv/%stream% best
GOTO end
:end
#CHOICE /C:rqn /M "[R]etry, [Q]uit or [N]ew"
IF ERRORLEVEL 3 GOTO start
IF ERRORLEVEL 2 GOTO quit
IF ERRORLEVEL 1 GOTO qual
GOTO quit
:quit
echo "bye."
#PAUSE
Thank you guys!
You can use >> to put the output of a command in text file. For example:
echo hi everyone >>textfile.txt
will add "hi everyone" to the last line of the text file.
You can also use > to add it to the first line instead.

My batch script doesn't use if command correctly

I've spent a few days trying to get this batch script to work, but it just does not seem to work properly. It seems to just do whatever it wants after it prompts me to set a variable and i set it.
For example, I might enter n when it says that it doesn't seem to exist, and it will just end the script like it should. But if I re-open it, and it says the same thing as before, and I enter n again, it might just jump to :DeleteCalc, as if I typed y.
Here's my script:
#echo off
:Begin
color fc
title My script
cls
if not exist "C:\calc.exe" (
echo calc.exe doesn't seem to exist. Attempt deletion anyway? ^(Y/N^)
set "calcnotexist="
set /p "calcnotexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal EnableDelayedExpansion
if not !calcnotexist!==!calcnotexist:^"=! set "calcnotexist="
endlocal & if "%calcnotexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto Begin
)
if /i "%calcnotexist%"=="Y" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="Yes" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="N" goto End
if /i "%calcnotexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto Begin
)
:calcDoesExist
title My script
cls
echo calc.exe found. Delete? ^(Y/N^)
set "calcexist="
set /p "calcexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal enabledelayedexpansion
if not !calcexist!==!calcexist:^"=! set "calcexist="
endlocal & if "%calcexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto calcDoesExist
)
if /i "%calcexist%"=="Y" goto DeleteCalc
if /i "%calcexist%"=="Yes" goto DeleteCalc
if /i "%calcexist%"=="N" goto End
if /i "%calcexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto calcDoesExist
:DeleteCalc
cls
echo Deleting...
if not exist C:\calc.exe goto Success
del /f /q C:\calc.exe >nul 2>nul
if not exist C:\calc.exe goto Success
echo Fail!
echo.
echo calc.exe could not be deleted.
echo.
pause
goto End
:Success
echo Deleted!
echo.
echo calc.exe successfully deleted.
echo.
pause
goto End
:End
exit /b
What could I possibly be doing wrong?
Thanks
P.S. I tested this by opening CMD and running the batch script multiple times in there. (but it also doesn't work right when just double clicking it)
If you restructure your script there will be no need for the extended If blocks and therefore no necessity to EnableDelayedExpansion. Also if you use Choice you will not have to do all of the verification of responses.
Example:
#Echo Off
Title My script
Color FC
:Begin
If Exist "C:\calc.exe" GoTo calcDoesExist
Echo(calc.exe doesn't seem to exist.
Choice /M "Attempt deletion anyway"
If ErrorLevel 3 (ClS & GoTo Begin)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo Success
GoTo End
:calcDoesExist
Echo(calc.exe found.
Choice /M "Delete"
If ErrorLevel 3 (ClS & GoTo calcDoesExist)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo DeleteCalc
GoTo End
:DeleteCalc
ClS
Echo(Deleting...
Del /A /F "C:\calc.exe">Nul 2>&1
If Not Exist "C:\calc.exe" GoTo Success
Echo(Fail!
Echo(
Echo(calc.exe could not be deleted.
GoTo End
:Success
Echo(
Echo(Deleted!
Echo(
Echo(calc.exe does not exist.
:End
Echo(
Echo(Exiting...
Timeout 3 /NoBreak>Nul
Exit /B

How to find a certain word in a file without using ERRORLEVEL (batch)

I can use ERRORLEVEL, but tried and with a loop it failed.
I am writing a batch "shell."
Since I have tried and tried, I am finally asking for help.
The reason I don't want to use errorlevel is because the loop.
(FULL) SHELL
#set /p build=<"C:\Users\%username%\Desktop\WellOS2\WellOS\Build".txt
#title WellOS V.%build%
#echo off
goto boot
:register
cls
echo You are registering...
echo If this is an error press CTRL + C NOW...
pause
cls
set /p user= Enter your username:
set /p passwordreg= Enter your password:
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%"
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%\Documents"
echo %passwordreg% >"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
echo 2 >"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
echo Your done.
pause
goto welloslog
:booterror
echo Sorry the boot file has an error. Check the user manual for BOOT$
pause
:boot
set /p boot=<"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
if %boot% == 1 goto register
if %boot% == 2 goto welloslog
goto booterror
cls
:ERROR
cls
echo ----------ERROR-------------------
echo %error%
pause
goto %back%
:welloslog
cls
echo Welcome to WellOS2!
echo ----------------LOGIN-------------
set /p user= Username:
if exist "C:\Users\%username%\Desktop\WellOS2\Users\%user%" goto pass
set error= Sorry that account doesn't exist.
set back=welloslog
goto welloslogerror
:pass
set /p password=<"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
set /p passwordlog= Password:
if /i %passwordlog% == %password% goto wellos
set error= Sorry! wrong password.
set back= welloslog
goto error
:wellos
cls
:wellosnocls
echo --------------MAIN---------------
echo type help for help
set /p command= #:
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" set type=sys
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" set type=pro
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" goto po
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" goto po
set error= !Unreconized program/system program!
set back=wellos
goto error
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode"
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
PROGRAM OPENER (What I am talking about, and having problems with...)
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode" goto iftl
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
findstr "targetstring" datafilename >flagfilename
for %%a in (flagfilename) do if %%~za==0 echo not found
for %%a in (flagfilename) do if %%~za neq 0 echo found
beyond that, your question is too vague.
The following command returns all lines of a text file textfile.txt that contain the word word (remove the /I switch if you want the search to be case-sensitive):
findstr /I /L "word" "textfile.txt"
With for /F you can capture the output and test whether it is empty, as the loop does not iterate if no match is encountered:
set "FOUND="
for /F "delims=" %%F in ('
findstr /I /L "word" "textfile.txt"
') do (
set "FOUND=Yes"
)
if defined FOUND (
echo One or more matches found.
rem do something...
) else (
echo No match found.
rem do something else...
)
Type for /? and if /? in command prompt to get details about the used commands.
There is also a way to use ErrorLevel implicitly, meaning you do not have to query its value by something like %ErrorLevel%, !ErrorLevel! or if ErrorLevel, namely when using conditional command separators:
the && separator executes the following command only in case the previous one succeeded, that is, it returned an ErrorLevel of 0; (findstr returns 0 in case a match is encountered;)
the || separator executes the following command only in case the previous one failed, that is, it returned an ErrorLevel other than 0; (findstr returns a non-zero ErrorLevel in case no match is encountered;)
The following line of code demonstrates the usage:
findstr /I /L "word" "textfile.txt" && (echo One or more matches found.) || echo (No match found.)

Can only write one word on chat batch file

The code below is the part of my program. My problem is that when i enter my message it works perfectly if its 1 word. but if it is more it says goto was expected. the Q and R options are needed to refresh the chat and pop up a quit prompt.
set /p M=Enter Your Message:
if %M%==Q goto B
if %M%==q goto B
if %M%==R goto A
if %M%==r goto A
echo %U%: %M% >>%S%.txt
What should i do?
ps. this is my first quistion on here sorry if formating is wrong)
If the input has more than one word, the parser will see, after variable replacement
if this is a test==Q goto B
which is an invalid command.
Simplest solution is to use quotes
if "%M%"=="Q" goto B
....
will be interpreted as
if "this is a test"=="Q" goto B
edited to adapt to comments
This is a skeleton of a chat script with "auto update" in the terms indicated in the comments.
#echo off
setlocal enableextensions disabledelayedexpansion
rem Configuration
set "chatFile=c:\temp\chat.txt"
set "lastSize=-1"
:selectOption
rem Update screen
call :refresh
rem retrieve user selection
>nul choice /c rqw /n /t 3 /d r /m ""
rem Check what has been selected
if errorlevel 3 call :write & goto :selectOption
if errorlevel 2 goto :quit
rem Select another option
goto :selectOption
:refresh [bForceRefresh]
rem Check if refresh is being forced
if not "%~1"=="" set "lastSize=-1"
rem Ensure we have a file
if not exist "%chatFile%" >"%chatFile%" echo(
rem Check if we can skip the refresh.
rem If file has no changed its size there are no changes in content
for %%a in ("%chatFile%") do if %%~za leq %lastSize% (
goto :skipRefresh
) else (
set "lastSize=%%~za"
)
rem Paint the screen
cls
type "%chatFile%"
rem Show the options
echo(
<nul set /p ".=[R]efresh [Q]uit [W]rite ?"
:skipRefresh
goto :eof
:write
setlocal
rem Ask message
echo(
echo(
set "message="
set /p "message=What do you want to say? >"
rem If there is a message, write to output file,
rem else force screen refresh to remove the message question
if defined message (
setlocal enabledelayedexpansion
>>"%chatFile%" echo(%time% :[ %username% ]: !message!
endlocal
) else (
call :refresh forceRefresh
)
endlocal
goto :eof
:quit
cls
exit /b

How to treat user input as two words instead of one in batch

How do you treat a user prompt as two words instead of one? for example,
set /p input=examine door
set /p input=examine wall
would each take you to
:door
#echo door
:wall
#echo wall
I want a user to be able to type "examine" and then anything else and have it navigate to the correct label. I think there's some kind of wildcard I need to use but I'm not sure exactly how to do it.
May be something like this ?
#echo off
set /p input=action :
for /f "tokens=1-2 delims= " %%a in ("%input%") do (
goto :%%~a_%%~b >nul 2>&1 || echo no such action.
)
exit /b 0
:examine_door
#echo door examined
goto :eof
:examine_wall
#echo wall examined
goto :eof
EDIT - goto shows a strange bug when called with conditional execution and switches to command prompt context.So better CALL to be used. Pretty interesting bug and goto, setlocal and call does not work
#echo off
set /p input=action :
for /f "tokens=1-2 delims= " %%a in ("%input%") do (
call :%%~a_%%~b >nul 2>&1 || call :last_resort
)
exit /b 0
:examine_door
#echo door examined
goto :eof
:examine_wall
#echo wall examined
goto :eof
:last_resort
#echo nothing more can be done
goto :eof
Here's an example of how you have take the text from the second token onward.
#echo off
set input=examine door
for /f "tokens=1,*" %%a in ("%input%") do echo goto :%%b
pause

Resources