display a variable like %%i in for statements in variable? batch - batch-file

How do I use a variable like %%i in a permanent variable?
(I don't really know the correct terms, so I hope anyone can figure out what I mean)
This is the code I am using:
#echo off
color 0f
goto number
:number
title number
cls
echo number of options?
set /p num=
goto option
:option
for /l %%i in (1,1,%num%) do (
cls
echo Name nr. %%i
echo Enter a option
set /p n%%i=
echo %%i = %n%%i% >> log.txt
)
goto select
:select
cls
echo %n2%
pause >nul
the "%n2%" works for whatever you put in second, but when I try to print it into a file ( echo %%i = %n%%i% >> log.txt ) it doesn't work.
I know the "%n%%i%" is not correct, But I don't really know what to actually put there.

:option
for /l %%i in (1,1,%num%) do (
cls
echo Name nr. %%i
echo Enter an option
set /p option%%i=
)
goto select
:select
set option>log.txt
cls
echo %option2%
You may like to consider this.
The command
set option
will show every environment variable that starts option in the format option1=Gido, which is why I changed n to option (there are other variables set that start n)

Related

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)

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.

Making a batch file do something once

I'm making a game and I want a personalized username option that only appears once.
Here is an example:
#echo off
:onetime
echo please enter a username
echo.
set /p newuser=%newuser%:
echo %newuser%> cfg.txt
goto menu
:menu
for /f "tokens=* delims=" %%x in (cfg.txt) do echo %%x
cls
...
I'm trying to figure out how to make :onetime happen once, so that it sends the username to cfg.txt
Anyone know how?
I have cleaned up your code and provided a completed working script, and noted where you will put your game code.
Although Delayed expansion is not needed for this code, I have placed it in the script as you had it in your original script.
Please be mindful of the variable names I have chosen as they are used in several locations.
I have tried to comment the code with info on what it is doing, and I would be happen to explain further if needed.
I'd like to actually play your game when you are completed with it, if I may. :)
Hope that helps.
Ben
BPG.cmd
REM Script: BPG.cmd
REM Version: 1.0
REM Description: Game to play about Monsters.
Rem Notes: Currently Implementing Menu System.
Rem Sets up Variables and checks if the script needs to be re-called.
#(
SETLOCAL ENABLEDelayedExpansion
echo off
SET "eLvl=0"
SET "ScriptFolder=%~dp0"
SET "Log=%~dpn0.log"
SET "ConfigFile=%~dpn0_cfg.txt"
IF /I "%~1" NEQ "MAX" (
ENDLOCAL
ECHO.Game not started Maximized, Opening in a New Window by Running: Start "BPG 1 A Batch of Monsters" /MAX "%~dpnx0" MAX
Start "BPG 1 A Batch of Monsters" /MAX "%~dpnx0" MAX
EXIT /b %eLvl%
)
COLOR 2
)
REM Calls Main Function.
CALL :Main
REM Ends the script.
(
ENDLOCAL
EXIT /b %eLvl%
)
REM Main Function, most of your coding goes here, and this function calls sub functions.
:Main
Rem Check if Config file exists, if it does not, then call the New User Function.
IF NOT EXIST "%ConfigFile%" (
CALL :NewUser
)
Rem Load Username from Config file.
FOR /F "Tokens=*" %%A IN ('Type "%ConfigFile%"') DO (
SET "_UserName=%%~A"
)
Rem Call Menu System
CALL :Menu
REM Based off the option chosen Either Start a new Game or Skip to the End.
REM ECHO.CALL %_Menu_Choice%
CALL %_Menu_Choice%
GOTO :EOF
:NewUser
SETLOCAL
REM Get the Username Input
SET /P "_User=Please Enter a Username: "
REM Output the Username to the config file, overwriting all the file contents:
echo.%_User%>"%ConfigFile%"
ENDLOCAL
GOTO :EOF
:Menu
SETLOCAL
REM Output the Config file contents:
Type "%ConfigFile%"
REM Clear the screen
cls
echo ______ _______ _______
echo I ___ \ I ____ I I ____ \
echo I I I II I II I I \/
echo I I__/ / I I____II I I
echo I __ I I _____I I I ____
echo I I \ \ I I I I \_ I
echo I I___I II I I I___I I
echo I______/ I_/ I_______I A BATCH OF MONSTERS
echo.
echo.
echo 1) Begin
echo.
echo 2) Exit
echo.
set /p "_Choice=%_UserName%, Enter a Number: "
(
REM End the local variable Space, and Set return variables based on the choice, or re-draw the menu.
ENDLOCAL
IF /I "%_Choice%" EQU "1" (
REM ECHO.%_Choice% EQU 1
SET "_Menu_Choice=:Begin_Game"
) ELSE (
IF /I "%_Choice%" EQU "2" (
REM ECHO.%_Choice% EQU 2
SET "_Menu_Choice=GOTO :EOF"
) ELSE (
ECHO.%_Choice% Not Valid!
PAUSE
GOTO :Menu
)
)
)
goto :EOF
:Begin_Game
REM All the remaining code for your game should probably go here.
GOTO :EOF
try checking file existence :
#echo off
:onetime
setlocal enableDelayedExpansion
if not exist "cfg.txt" (
echo please enter a username
echo.
set /p newuser=%newuser%:
echo !newuser!> cfg.txt
goto menu
)
:menu
for /f "tokens=* delims=" %%x in (cfg.txt) do echo %%x
cls

Why am I getting "ECHO is OFF/ON"?

Simple question: why is ECHO is OFF/ON being printed in a .txt file instead of the users' input? I tried various solutions - none of them worked. Any and all help will be appreciated.
Code
#echo off
:start
del "test.txt"
cls
set /p test_test = "> "
echo %test_test% >> test.txt
for /f "delims=" %%a in (test.txt) do (
set file = %%a
)
echo %file%
pause
The ECHO command with no parameters outputs the status of ECHO, which in this case you've set to off. Because your %test_test% variable is empty, (due to you setting a variable named %test_test %), the ECHO command is being entered with no parameters.
#echo off
:start
cls
set /p "test_test= > "
(echo %test_test%)>test.txt
for /f "delims=" %%a in (test.txt) do (
set "file=%%a"
)
echo %file%
pause
As you may have noted you werre also setting a variable named %file % too.

IF NOT EXIST against Prompting user to select a directory

If I were to create a condition where a user selects a directory by number, how would I test that to make sure it’s valid?
In other words, if a user were prompted:
C:\Program Files
C:\Userdata
Please select a directory: 3
In this unique scenario, how can I test against that and inform the user that 3 is a wrong selection and then loop back to the sub-routine?
I’ve sort of hit a dead end as I thought the “if not exist” would work.
I’ve tried the following without success:
If %errorlevel% equ 1 (command) else (command)
If errorlevel 1 (command) else (command)
If not exist !acctDir!!userDir! (command) else (command).
This is what I have:
:dir
echo.
set c=0
For /f %%a in ('dir !acctDir! /B /A:D') do (
set /a c+=1
echo !c! %%a >>!log!
echo !c! %%a
set dir!c!=%%a
)
echo.
set /p userIn=" Please select a directory [1-!c!]: "
set userDir=!dir%userIn%!
echo ***DEBUG*** Path=[!acctDir!\!userDir!]
pause
if not exist "!acctDir!\!userDir!" (
echo.
echo That is not a valid selection. Please try again. >>!log!
echo That is not a valid selection. Please try again.
echo.
ping 127.0.0.1 -n 3 -w 1000 >nul
cls
goto dir
) else (
echo.
echo You selected !userDir! for your data retrieval. >>!log!
echo You selected !userDir! for your data retrieval.
echo.
ping 127.0.0.1 -n 3 -w 1000 >nul
goto string
)
)
When I do some DEBUG testing to echo out the path before the IF statement is ran I get:
1 Jan_14_2014_12_49_11_900PM
2 Jan_20_2014_6_56_55_953PM
Please select a directory [1-2]: 3
***DEBUG*** Path=[x:\101004357\]
Press any key to continue . . .
So it returns a path as having the account number but not the sub-directory because of obvious reasons as input 3 is nothing. However, IF NOT EXIST should be followed then, right?
I don’t think Windows knows the numbers are related to the sub-directories?
So, I need a condition stating, IF NOT EXIST any subdirectory (which I thought would be the variable !userDir!). But the !userDir! is being assigned as nothing, so this is why it’s not working. Then I think I would need to get a list of the sub-directories to run this statement against.
**This is just 1 of 12 sub-routines, so these are the correct variables.
Any idea of how I can complete this task?
I was able to resolve the issue by solving the issue if there was a NULL output. Setting the variable around brackets and setting it to equal the null output surrounded by empty brackets allows me to test against the user input.
Simply did the following:
if [!userDir!]==[] (
echo.
echo That is not a valid selection. Please try again. >>!log!
echo That is not a valid selection. Please try again.
echo.
ping 127.0.0.1 -n 3 -w 1000 >nul
cls
goto dir
) else (
echo.
echo You selected !userDir! for your data retrieval. >>!log!
echo You selected !userDir! for your data retrieval.
echo.
ping 127.0.0.1 -n 3 -w 1000 >nul
goto string
)
)
Try this:
#echo off
setlocal Enabledelayedexpansion
set c=0
set "acctDir=U:\scripts\batch"
For /f %%a in ('dir !acctDir! /B /A:D') do (
set /a c+=1
echo !c! %%a
set dir!c!=%%a
set valid=!valid! !c!
)
:StartOver
set /p userIn=" Please select a directory [1-!c!]: "
set userDir=!dir%userIn%!
REM echo valid=%valid%
for %%a in (%valid%) do (
if %userIn% NEQ %%a (
set txt=!userIn! is not a valid selection. Please try again.
) ELSE (
set txt=You selected !userDir! for your data retrieval.
Goto :out
)
)
:out
If "%txt:~0,3%" EQU "You" Echo %txt%
if "%txt:~0,3%" NEQ "You" Echo %txt% & goto :StartOver
This should work: The trailing backslash tests only for a folder and not for a filename.
If not exist "!acctDir!\!userDir!\" (command) else (command)
#ECHO OFF
SETLOCAL
SET acctdir=.
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET "$alphabet=0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
FOR /f "delims=" %%a IN ('dir "%acctDir%" /B /A:D') DO CALL :setchoices "%%a"
IF NOT DEFINED $_%$alphabet:~0,1% GOTO :EOF
FOR /f "tokens=2*delims=_=" %%a IN ('set $_') DO ECHO(%%a : %%b
choice /c %$$% /m "Choose from menu "
SET /a chosen=%ERRORLEVEL%-1
CALL SET $$=%%$$:~%chosen%,1%%
CALL SET $$=%%$_%$$%%%
ECHO CD "%acctDir%\%$$%"
GOTO :EOF
:setchoices
FOR %%i IN (%$alphabet%) DO IF NOT DEFINED $_%%i (
SET "$_%%i=%~1"
SET "$$=%$$%%%i"
GOTO :EOF
)
GOTO :eof
This works - I used . as acctdir for testing. Your choice of letters and numbers for choicenames in $alphabet
Target directory just echoed - remove the echo before the cd to activate.

Resources