Test for and remove substring in user input - batch-file

I want to create a batch file that echoes text that it receives as part of a user-inputted command.
#echo off
Echo execute a command
Set /p command=
if "%command%"=="echo 'some text'" goto echo
::my aim is to make "echo" ignored by System and Only read "'some text'"
:: like "set text_to_echo='some text'
:echo
echo %text_to_echo%
Asking the user for the command first and then asking the user what to echo, like below, is not an option
#echo /p
set /p text=
if "%text%=="echo"
:echo
set /p tex1="Enter text to echo"
echo "%tex1%"

You could use this:
#echo off
Echo execute a command
Set /p "command="
if NOT "%command%"=="%command:echo =%" goto echo
pause
:echo
SET "text_to_echo=%command:~5%"
echo.%text_to_echo%
pause
Note that I also fixed your if, and put a pause after your if so you know whether it goes to :echo or not.

You want to split your Input into a first word (token) and the rest. You can do this with a for:
#echo off
Echo execute a command
Set /p "commandstring=# "
for /f "tokens=1,* delims= " %%a in ("%commandstring%") do (
set "command=%%a"
set "params=%%b"
)
if /i "%command%"=="echo" goto :_echo
...
:_echo
echo %params%
REM also possible (at least for "echo", but I guess, that's just an example):
%command% %params%

Related

I want to have multiple echo and echo. below a pause and below a set /p variable= befor pressing any key in a batch file

I want the line of code below to work or something that will do the same and i want the echo and echo. to show befor i press any key
set /p variable=
echo.
echo test
echo.
echo test
::ect
and I want the line of code below to work or something that will do the same and i want the echo and echo. to show befor i press any key
pause
echo.
echo test
echo.
echo test
::ect
I tried this (I have not tried it with pause)
#echo off
for /f %%A in ('echo prompt $E^| cmd') do set "esc=%%A"
cls
echo *other text*%ESC%[2A
set /p variable=
echo %ESC%[1B
I was only able to have one echo or one echo. after set /p variable=, but I expected to be able to have multiple echo below set /p variable= and multiple echo. below set /p variable=
If i try to have more then one line of text then it takes the line of text above set /p variable= and moves it down below set /p variable= and combines it with the text i want below set /p variable=
So i want the set /p variable= and pause to pause after all the echo and echo.
I want it to look like for example this when i open the .bat file
Type the number of your choosing:
*other text*
Or this
Press any key to continue . . .
*other text*
sorry for posting the same thing so many times i promis that this is the last time
You are using ANSI escape codes. Just use them at the right place and with the proper parameters (numbers):
#echo off
for /f %%A in ('echo prompt $E^| cmd') do set "esc=%%A"
cls
echo/
echo/
echo *other text*
echo *additional text*
echo *some more text*
echo %ESC%[5A
set /p "variable=Enter var: "
echo %ESC%[2B
echo Thank you for your input.
Output on screen (where Hello is the manual input:
Enter var: Hello
*other text*
*additional text*
*some more text*
Thank you for your input.
You need enough space "above" set /p. It doesn't work at the very first line (after CLS) because you can't move the cursor to "line zero", so you need (at least) two (empty) lines (echo/).

pulling a variable from text file in a sentence

im currently making something along the lines of a sentence generator, it uses text files which have a list of words in them, for example celebrity.txt has a list of celebrities and this script both shuffles the text file into newcelebrity.txt and takes the first one from that list so its different every time, and ive run into a problem, i want it to be one line and that you can call a variable in the sentance youre typing, not break it down as it is right now, is there a way to have it "this $celebrity is really great" as of now, it works like this: https://gyazo.com/9ae8583ed5457709bd1c1dc9cc0cc106 and outputs as this https://gyazo.com/1a5a90f1fbf80faa73d71791a8c1c761, i dont mind the quotation marks at all, its just the way you input it.
Is there any way to make it work like i want it to or is this a limitation of batch files?
set /p message=Unity:
set /p input=The variable:
set /p after=Unity:
:gen
setlocal
cd ..
cd rcs
echo doing background work, please wait a few seconds :)
for /f "delims=" %%a in (%input%.txt) do call set "$$%%random%%=%%a"
(for /f "tokens=1,* delims==" %%a in ('set $$') do echo(%%b)>new%input%.txt
endlocal
cls
set "File=C:\Users\%USERNAME%\Desktop\gg\rcs\new%input%.txt"
set /a count=0
echo background work done :)
timeout /t 1 >nul
SETLOCAL enabledelayedexpansion
for /F "tokens=* delims=" %%a in ('Type "%File%"') do (
Set /a count+=1
Set "output[!count!]=%%a"
)
For /L %%i in (1,1,%Count%) Do (
Call :Action "!output[%%i]!"
pause
)
Exit
::*******************************************************
:Action
cls
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo %message% %1 %after%
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo if you want to go back and change your inputs type back
echo if you want to continue generating, type gen
echo.
set /p instruction=
goto %instruction%
::*******************************************************
To get rid of the quotation marks, just use %~1 instead of %1.
I'm assuming, you want to input something like 'this $celeb is great' instead of the first three set /p lines (as your output is already in one line).
I used some fixed variables to keep it short - of course you would fetch them from the user and the text file instead, as you already did.
#echo off
setlocal EnableDelayedExpansion
set "count=3"
set "output[3]=John"
set "sentence=this $celeb is great."
REM above would be your 'set /p' instead
call :action "!output[%count%]!"
goto :of
:action
echo !sentence:$celeb=%~1!
(just to be clear: $celeb is not a variable - it's just a string, that we replace later, so from user's perspective, it behaves like a variable)

How to display text beneath "set /p variable="

In this senario,
echo Write your name below.
echo.
set /p name="Enter here: "
echo.
echo *other text*
is there a way where the set /p name="Enter name: " doesn't pause the screen and also displays the text below.
I figured that since its a top down language it probably cannot, but there are many people on here with more experience who might no otherwise.
If you're using Windows 10, you can use VT100 escape sequences to move the cursor up and down, printing everything first and then getting user input afterwards.
#echo off
:: Generate an escape character. Normally I'd just use ALT+027,
:: but SO doesn't display those properly.
for /f %%A in ('echo prompt $E^| cmd') do set "esc=%%A"
:: The trick here is to write out everything and then move the cursor
:: back to where it needs to be
echo Write your name below.
echo(
echo(
echo(
echo *other text*%ESC%[2A
set /p "name=Enter here: "
:: When we're done, move the cursor to where it would have been if
:: we had written everything top-down
echo %ESC%[1B
You can store new line character in a variable and print it out
#echo off
setlocal EnableDelayedExpansion
(set LF=^
%=empty=%
)
echo Write your name below.
echo.
set /p name="Enter here:!LF!*other text*!LF!"

How to "hide" a text from Batch-File?

I want to know if there any solution to this:
Main.bat:
#echo off
goto 'input'
: 'input'
cls
set "inp="
set /p inp=What would you like to do?
set firstresponse=%inp:~0,5%
if %firstresponse%==help goto 'help'
pause
if /I %firstresponse%==check set firstresponse=dir && set
executeparttwo=%inp:~5%
if /I %firstresponse%==remov goto 'remove'
%firstresponse%%executeparttwo%
pause
goto 'input'
: 'remove'
set "firstresponse=" && set firstresponse=%inp:~0,6%
if /I %firstresponse%==remove set firstresponse=del
set executeparttwo=%inp:~6%
%firstresponse%%executeparttwo%
pause
goto 'input'
: 'help'
cls
echo Check = Dir in regular command prompt, checks a directory.
echo Remove = del in regular command prompt, deletes something.
pause
goto 'input'
if the User typed an invalid command, it will show like what CMD does ( 'command' is not recongnized...)
What i want to do is to replace the CMD invalid command text to my own one like "command" is an invalid command, but to do that i need to "hide" the CMD one (because if the user typed a invalid command it will not show him a "custom message")
I tried to use some Batch plugins like batbox, CursorPos etc... To replace the cursor position but i didn't get what i wanted. So if anyone have a solution i will be very appreciated!
Have a nice day, and thanks for reading!
Your splitting the command and parameters is not ideal, there is a much easier and safer way. Also, the method of an own subroutine for each command is suboptimal (especially, when you add more and more commands).
#echo off
call :commandlist REM build translation table
:input
REM get input line:
set /p "commandline=Enter Command: "
REM split to command and parameters
for /f "tokens=1,*" %%a in ("%commandline%") do (
set "command=_%%a"
set "params=%%b"
)
REM check for valid command:
set _|findstr /bi "%command%=" >nul || (
echo invalid command: '%command:~1%'.
goto :input
)
REM execute the command:
call %%%command%%% %params%
goto :input
:Commandlist
set "_check=dir /b"
set "_remove=del"
set "_help=:help"
set "_where=call echo %%cd%%"
set "_change=cd"
set "_apt-get=:apt"
set "_bye=exit /b" 'secret' exit command ;)
goto :eof
:help
echo Check = Dir in regular command prompt, checks a directory.
echo Remove = del in regular command prompt, deletes something.
echo Where = echo %%cd%% in regular command prompt, print working folder.
echo Change = cd in regular command prompt, change working folder
goto :eof
:apt
if /i "%~1" == "update" echo updating... & goto :eof
if /i "%~1" == "whatever" echo whatevering... & goto :eof
echo invalid command: '%command:~1% %1'
goto :eof
(Note to experienced batch users: yes I know there is a possibility for some "code injection")

Error Writing to file in .bat file

I have a .bat file that would ask your name and save it in a .txt file. If the file already exists, I want it to say "Your Name is ____"
#echo off
if exist BatchfileOutput.txt (
cls
FOR /F %%i IN (BatchfileOutput.txt) DO echo Your name is %%i
) else (
echo What is your name?
set /p %name%= )
echo %name% > BatchfileOutput.txt
pause
It prints ECHO is off, probably due to #echo off at the top. If I manually add text to the file, it displays the text. Could anyone help me get around this?
You need
set /p name=
not
set /p %name%=
which would set the variable named the current contents of NAME
It is set /P name= but not set /P %name%=.
The command echo %name% needs to be moved into the else block too. For this to work, delayed expansion must be established:
#echo off
if exist "BatchfileOutput.txt" (
cls
for /F "usebackq tokens=*" %%i in ("BatchfileOutput.txt") do echo Your name is %%i
) else (
echo What is your name?
set /P name=
setlocal EnableDelayedExpansion
> "BatchfileOutput.txt" echo !name!
endlocal
)
pause
I moved the redirection part to the front in order to avoid a trailing SPACE to be output also.
To avoid delayed expansion, you could avoid the parenthesised else block by using goto :Label as the last command of the if block, then omitting else and the parentheses, and then placing :Label before pause:
#echo off
if exist "BatchfileOutput.txt" (
cls
for /F "usebackq tokens=*" %%i in ("BatchfileOutput.txt") do echo Your name is %%i
goto :Label
)
echo What is your name?
set /P name=
> "BatchfileOutput.txt" echo %name%
:Label
pause
I quoted all file paths and therefore used the usebackq option of for /F in order to avoid trouble with such strings containing white-spaces. Furthermore, I stated the tokens=* option for the for /F loop to read the full line even in case the name consists of multiple words.

Resources