bat file to find and replace commandlines in a .txt - batch-file

So i've been looking at articles to see how to get this to work but everything has been going over my head. I'm trying to create a bat file that finds a game commandline.txt and changes a certain commandline for example a resolution
-width=1280
-height=720
to
-width=800
-height=400
for exmaple
and for it to save as the same .txt
I have written this for an example of code i want to use in a similar fashion and for you to get an idea of what i'm doing
#echo off
:MENU
CLS
echo+
echo 1 - game1
echo 2 - game2
echo+
echo+
SET /P MainMenuInput=Enter an option and press ENTER:
if %MainMenuInput% == 1 (
findstr "" "X:\game1\commandline.txt"
echo.%str%
set str=%str:-width=1280 -height=720=-width=800 -height=400%
echo.%str%
)
GOTO :MENU
if %MainMenuInput% == 2 (
findstr "" "X:\game2\commandline.txt"
echo.%str%
set str=%str:-width=1280 -height=720=-width=800 -height=400%
echo.%str%
)
GOTO :MENU
basically i have 2 games - i select number 1 which is game 1 and then it should change the width and height
So if i change it to this, it still doesn't work
#echo off
:MENU
CLS
echo+
echo 1 - Dev_NG
echo 2 - Dev_NG-Live
echo+
echo+
SET /P MainMenuInput=Enter an option and press ENTER:
if %MainMenuInput% == 1 (
set "search=-width=1280"
set "replace=-width=800"
set "textFile=%SettingFile%.txt"
for /f "delims=" %%i in ('type "%X:\game1\commandline.txt%" ^& break ^> "%X:\game1\commandline.txt%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
>>"%textFile%" echo(!line!
endlocal)

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.

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

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)

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

How to map numbers to a variable

I have the following script but I want to map the numbers to the variable but do not know how to. So if a user enters 0, I want it to search for the event name NewUser.
#echo off
mode con:cols=40 lines=40
set /p customerID="Enter Customer ID: "
CLS
:MENU
ECHO.
ECHO ...............................................
ECHO PLEASE SELECT THE EVENT FROM THE MENU BELOW
ECHO ...............................................
ECHO.
ECHO Event Code Event Name
ECHO.
ECHO 0 NewUser
ECHO 1 ExistingUser
ECHO 2 EmailAdded
ECHO 3 AccountProblem
ECHO 4 Lost
ECHO.
SET /P event=Type the event code and then press ENTER:
IF %event%==0 set event=NewUser GOTO find
IF %M%==1 set event=ExistingUser GOTO find
IF %M%==2 set event=EmailAdded GOTO find
IF %M%==3 set event=AccountProblem GOTO find
IF %M%==4 set event=Lost GOTO find
pause
:find
pause
setlocal enableextensions disabledelayedexpansion
pause
set "sourceFolder=C:\test"
set "targetFolder=C:\test2"
pause
set "customerID=%customerID%"
set "NewUser=%Event%"
pause
for /f "delims=" %%a in ('
findstr /m /s /l /c:"%customerID%" "%sourceFolder%\*"
^| findstr /f:/ /m /l /c:"%event%"
') do (
copy "%%~fa" "%targetFolder%"
)
pause
The first version of your code was closer to correct solution than current one; you need to use two nested for /F loops as follows:
for /f "delims=" %%a in ('
findstr /I /m /s /l /c:"%customerID%" "%sourceFolder%\*.txt"
') do for /f "delims=" %%A in ('
findstr /I /m /l /c:"%event%" "%%~fa"
') do (
rem 'copy' command is merely displayed using ECHO for debugging purposes
ECHO copy "%%~fa" "%targetFolder%"
)
Next commented code snippet could help to improve the script:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "customerID="
:customerID
set /p customerID="Enter Customer ID: "
if not defined customerID goto :customerID
REM instead of above test, you could apply next statement about `set /P`:
REM If the user does not enter anything (just presses return)
REM then the variable will be unchanged and an ERRORLEVEL will be set.
rem CLS
:MENU
ECHO.
ECHO ...............................................
ECHO PLEASE SELECT THE EVENT FROM THE MENU BELOW
ECHO ...............................................
ECHO.
ECHO Event Code Event Name
ECHO.
ECHO 0 NewUser
ECHO 1 ExistingUser
ECHO 2 EmailAdded
ECHO 3 AccountProblem
ECHO 4 Lost
ECHO.
REM SET /P M=Type the event code and then press ENTER:
choice /C 01234 /M "Type the event code"
REM 0 means that an user's reply to "Terminate batch job (Y/N)?" was not "y"
IF %ERRORLEVEL% EQU 0 echo "Ctrl-C" or "Ctrl-Break" pressed&goto :NoSearch
REM 255 means another error
IF ERRORLEVEL 255 goto :MENU
REM ERRORLEVEL number Specifies a true condition if the last program run
REM returned an exit code EQUAL TO OR GREATER THAN the number
REM specified.
IF ERRORLEVEL 1 set "event=NewUser"
IF ERRORLEVEL 2 set "event=ExistingUser"
IF ERRORLEVEL 3 set "event=EmailAdded"
IF ERRORLEVEL 4 set "event=AccountProblem"
IF ERRORLEVEL 5 set "event=Lost"
REM Note that in above code, ERRORLEVEL parameters are tested in INCREASING order
REM Used only in this special case
REM (no need of GOTO statement, 'event' variable is set correctly)
REM
REM although CHOICE /? says:
REM When you use ERRORLEVEL parameters in a batch program,
REM list them in decreasing order.
:NOTE
set "sourceFolder=D:\test"
set "targetFolder=D:\test2"
rem ??? set "customerID=%customerID%"
rem ??? set "event=%event%"
rem debugging output
echo looking for "customerID=%customerID%" "event=%event%"
for /f "delims=" %%a in ('
findstr /I /m /s /l /c:"%customerID%" "%sourceFolder%\*.txt"
') do for /f "delims=" %%A in ('
findstr /I /m /l /c:"%event%" "%%~fa"
') do (
rem 'copy' command is merely displayed using ECHO for debugging purposes
ECHO copy "%%~fa" "%targetFolder%"
)
:NoSearch
pause
Change your For loop like this and retest:
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MSC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%event%"'
) DO COPY "%%A" "%targetFolder%"
EDIT
I have added a modified version of your script to include the new requirement of a three digit event code. Just adjust it's value in the script as necessary, (lines nineteen to twenty three).
#ECHO OFF
MODE CON:COLS=52 LINES=40
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
(SET sourceFolder=C:\test)
(SET targetFolder=C:\test2)
SET /P "customerID=Enter Customer ID: "
:MENU
CLS
ECHO=
ECHO= ..................................................
ECHO= PLEASE SELECT THE OPTION FROM THE EVENT MENU BELOW
ECHO= ..................................................
ECHO=
ECHO= Option Event Name Event Code
ECHO=
ECHO. 1. NewUser A00
ECHO. 2. ExistingUser A01
ECHO. 3. EmailAdded A02
ECHO. 4. AccountProblem A03
ECHO. 5. Lost A04
ECHO=
CHOICE /C 12345 /M "CHOOSE AN OPTION"
SET "Option=%ERRORLEVEL%"
FOR /F "TOKENS=1-4 DELIMS=. " %%A IN ('FINDSTR/BC:"ECHO. " "%~f0"'
) DO IF "%%B"=="%Option%" (SET "Name=%%C" & SET "Code=%%D")
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MISC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%Name%"'
) DO COPY "%%A" "%targetFolder%"
PAUSE
Please make sure that %sourceFolder% is a full path and %targetFolder% already exists, (see line six).

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