Find and Replace a batch file using DOS - windows

This is what i need.
Lets say there is a file temp.txt
Lets say temp.txt has the following content :
name=#name
age=#age
email=#email
And my batch file create.bat should ask for the three parameters as input from the user,
and then replace the temp.txt with the respective values.
Say.
Pls enter your name:Tom
Tom - Confirm Y/N: Y
<<now anywhere the temp.txt says #name, it is replace by Tom>>
Please help me write a script for this??
Thanks,
Naveen.

rem #echo off
setlocal enabledelayedexpansion enableextensions
rem Don't use the same file name for both here
set InputFile=temp.txt
set OutputFile=temp2.txt
call :ask name name
call :ask age age
call :ask "e-Mail address" email
del %OutputFile% 1>nul 2>&1
for /f "delims=" %%l in (%InputFile%) do (
set Line=%%l
set Line=!Line:#name=%name%!
set Line=!Line:#age=%age%!
set Line=!Line:#email=%email%!
>>%OutputFile% echo.!Line!
)
goto :eof
rem :ask "placeholder title" variable_name
:ask
set /p %2=Please enter your %~1:
choice /M "!%2! - Confirm"
if errorlevel 2 goto ask
goto :eof

Related

Issue with "findstr" using Batch

Below, I wrote some code. It detects if a Micro-SD card is inserted into the computer and if so, it will ask to enter your pin. After you enter the pin, it will look through the card for a text file that contains a list of pins.
:start
cls
echo.
echo.
if exist E:\ (
goto enterPin
) else (
echo INSERT YOUR CARD
)
timeout 1 >nul
goto start
:enterPin
echo Enter Account Pin: %chip%
set /p pin=": "
:: Finding the specified pin
findstr /m "%pin%" E:\Chip\CardInfo.txt >Nul
if %errorlevel%==0 (
echo Pin "%pin%" is valid
timeout 1 >nul
goto account
)
if %errorlevel%==1 (
echo Pin "%pin%" is invalid
pause
goto start
)
:account
cls
:: Finds the name of the account owner and continues
setlocal enableextensions disabledelayedexpansion
for /F "tokens=2 delims=/" %%a in ('findstr /I "%pin%/" E:\Chip\CardInfo.txt') do set "user=%%a"
for /F "tokens=3 delims=/" %%b in ('findstr /I "%pin%/%user%/" E:\Chip\CardInfo.txt') do set "balance=%%b"
echo.
echo.
echo Welcome, %user%.
echo.
echo ACCOUNT BALANCE: $%balance%
echo.
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
choice /c 1234 >nul
if %ERRORLEVEL% EQU 1 goto deposit
if %ERRORLEVEL% EQU 2 goto withdraw
if %ERRORLEVEL% EQU 3 exit
if %ERRORLEVEL% EQU 4 goto account
:deposit
echo.
echo.
set /p add="Money to Deposit: "
set /a moneytoadd=%balance%+%add%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /f E:\Chip\CardInfo.txt /o -
goto account
:withdraw
echo.
echo.
set /p sub="Money to Withdraw: "
set /a moneytosub=%balance%-%sub%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /f
E:\Chip\CardInfo.txt /o -
goto account
endlocal
Here's when the issue comes in. A pin consists of 4 numeric characters (ex. 1234), but if there's two pins with the same characters (ex. 1234, 6543), it will say the pin is valid. So for example, if I type 4, it will just look for just the number 4 in the file. And will say the pin is valid. Even though, just the number 4 is not an existing pin. My guess is that it's a flaw with "findstr". But I'm not sure.
Contents of "CardInfo.txt":
1234/Test User/1000
6543/Another Test User/2000
use REGEX (using <StartOfLine><PIN></>):
findstr /m "^%pin%/" E:\Chip\CardInfo.txt >Nul
where ^ is "Start of Line".
Here is what exactly does what you want:
#echo off
::add your path below
for /f %%a in (file.txt) do (
call :funch %%a
)
:funch
set input=%1
set "modifiedinput=%input:~0,4%"
set /p pin=Enter Account Pin:
if %modifiedinput% equ %pin% ( goto authentication_passed) else ( goto authentication_failed)
:authentication_passed
echo auth passed
rem your code
pause >nul
exit
:authentication_failed
echo auth failed
goto funch
it will read the input from file and then extract first four characters which in your case is the pin.
I rewrote the entire batch file to be more fail safe on execution:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem endlocal is executed implicitly by cmd.exe on exiting batch file processing.
:Begin
cls
echo\
echo\
if exist E:\ goto enterPin
echo INSERT YOUR CARD
%SystemRoot%\System32\timeout.exe /T 1 >nul
goto Begin
:enterPin
set "pin="
set /p pin="Enter account pin for %chip%: "
if not defined pin goto enterPin
set "pin=%pin:"=%"
if not defined pin goto enterPin
for /F delims^=01234567890^ eol^= %%I in ("%pin%") do goto enterPin
rem Finding the specified pin.
%SystemRoot%\System32\findstr.exe /B /L /M /C:"%pin%/" E:\Chip\CardInfo.txt >Nul
if errorlevel 1 (
echo Pin "%pin%" is invalid.
pause
goto Begin
)
echo Pin "%pin%" is valid.
%SystemRoot%\System32\timeout.exe /T 1 >nul
:account
cls
rem Finds the name of the account owner and continues
for /F "tokens=2,3 delims=/" %%I in ('%SystemRoot%\System32\findstr.exe /B /L /C:"%pin%/" E:\Chip\CardInfo.txt') do set "user=%%I" & set "balance=%%J"
echo/
echo/
echo Welcome, %user%.
echo/
echo ACCOUNT BALANCE: $%balance%
echo/
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
%SystemRoot%\System32\choice.exe /c 1234 >nul
if not errorlevel 1 goto account
if errorlevel 4 goto account
if errorlevel 3 exit /B
if errorlevel 2 goto withdraw
:deposit
echo/
echo/
set "add="
set /P "add=Money to deposit: "
set /A moneytoadd=balance + add
call "%~dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /L /f E:\Chip\CardInfo.txt /o -
goto account
:withdraw
echo/
echo/
set "sub="
set /P "sub=Money to withdraw: "
set /A moneytosub=balance - sub
call "%dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /L /f E:\Chip\CardInfo.txt /o -
goto account
Issues fixed with this code:
There is the command START. For that reason it is not advisable to use the string start as label although it is possible.
It is advisable to avoid an IF (...) ELSE (...) condition if a simple IF condition with GOTO can be used too.
The usage of full qualified file names wherever possible avoids a batch file not running as expected on environment variables PATH (too often) or PATHEXT (rarely) are corrupted on the userĀ“s machine.
A user has the freedom to enter on a prompt done with set /P really anything from nothing to something resulting in further processing in a syntax error with an immediate exit of batch file execution on code not being prepared for any user input. For that reason the first set /P prompt is improved and validates if the user entered a string consisting only of digits.
The usage of FINDSTR is done with additional options to find the pin only at beginning of a line case-sensitive with a literal search and the next character must be a slash character.
The recommended syntax for ERRORLEVEL evaluation is used in the code.
The arithmetic expressions are written using the recommended syntax to work even if the user enters nothing or a string which cannot be converted to an integer number at all.
The command EXIT is used with option /B to just exit the processing of the batch file and not the entire command process.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
choice /?
cls /?
echo /?
findstr /?
for /?
goto /?
if /?
pause /?
rem /?
set /?
setlocal /?
timeout /?
Useful pages regarding to the improvements on code:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Syntax error in one of two almost-identical batch scripts: ")" cannot be processed syntactically here
DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/
Single line with multiple commands using Windows batch file
Safe number comparison in Windows batch file

How should I Create a Batch Menu based on List of Output

I think I may struggle to explain the how I want my batch script to behave so here goes. My script is meant to act as a menu system requiring user input. What I have managed so far is to send a list of datestamps to output to a user. However I am attempting to arrange the script so any timestamp can be selected such as 1,2,3 and based on a prompt for user input. Later I want to save that to a variable in which I can do another operation with afterwards.
So this is what an example of what I can see:
FOR /f "tokens=3 delims= " %%G IN ('%history% ^| findstr /C:"Start Time:"') DO (call :subroutine %%G)
:subroutine
echo %1
GOTO :EOF
My output now looks like this:
20150706232400
20150706232707
20150706232757
20150706233058
20150706233144
Any pointers appreciated. Thanks.
#echo off
setlocal EnableDelayedExpansion
rem Show menu and store options in an array
echo Available datestamps:
echo/
set i=0
FOR /f "tokens=3" %%G IN ('%history% ^| findstr /C:"Start Time:"') DO (
set /A i+=1
echo !i!. %%G
set "option[!i!]=%%G"
)
echo/
:getChoice
set /P "choice=Enter desired option: "
if "!option[%choice%]!" equ "" echo ERROR: no such option & goto getChoice
set "variable=!option[%choice%]!"
ECHO/
ECHO Selected datestamp: %variable%

Batch move files named in a text file to directories provided by text file

I need to move some files named in one text file to directories named in another different text file. Using Batch commands.
What I've tried.
#echo off
echo.
REM check if file is there
if exist K:\file_sync_diff\FileNameList.txt goto Label 1
REM display error
echo Can not find the File Name List
echo.
echo.
Pause
goto :eof
:Label 1
REM display that the file in the last check was found
echo found FileNameList.txt
REM check if file is there
if exist K:\file_sync_diff\FileDumpText.txt goto Label 2
REM display error
echo Can not find File Dump Text File
echo.
echo.
Pause
goto :eof
:Label 2
REM display that the file in the last check was found
echo found FileDumpText.txt
REM check if file is there
if exist K:\file_sync_diff\DirectoryNames.txt goto Label 3
REM display error
echo Can not find Directory Names Text File
echo.
echo.
Pause
goto :eof
:Label 3
REM display that the file in the last check was found
echo found DirectoryNames.txt
REM for loop to filter through every line in a file
echo.
for /f %%i in (K:\file_sync_diff\FileNameList.txt) do call :Sub %%i
goto Label 4
goto :eof
:Label 4
REM display message of the file being moved
echo.
echo Moving %1
REM copy the file just made to a directory with a name supplied in a text file
for /f %%i in (K:\file_sync_diff\DirectoryNames.txt) do call :Sub 2 %%i
echo.
goto :eof
:Sub
echo Writing %1
REM copy the contents of FileDumpText.txt to the file that was passed in the last method
type K:\file_sync_diff\FileDumpText.txt >> %1.txt
goto :eof
:Sub 2
REM moves the file to the directory supplied by label 4.
move /y %1.txt %1
echo.
goto :eof
Contents of FileNameList.txt
red
orange
purple
Contents of DirectoryNames.txt
K:\file_sync_diff\cat
K:\file_sync_diff\dog
K:\file_sync_diff\333
Not that it matters but the contents of FileDumpText.txt
Test text to be passed to the file
more text 1
more text 2
more text 3
The directories do exist in the K:\file_sync_diff folder.
Thank you for your help.
The end result should be the following
directory cat with red.txt inside with all of the contents of FileDumpText.txt inside it
directory dog with orange.txt inside with all of the contents of FileDumpText.txt inside it
directory 333 with purple.txt inside with all of the contents of FileDumpText.txt inside it
my suggestion with associative arrays:
#ECHO OFF &SETLOCAL
set "tfileA=K:\file_sync_diff\FileNameList.txt"
set "tfileB=K:\file_sync_diff\DirectoryNames.txt"
set "tfileC=K:\file_sync_diff\FileDumpText.txt"
for /f "tokens=1*delims=:" %%a in ('findstr /n $ "%tfileA%"') do set "$a%%a=%%b"&set /a countA=%%a
for /f "tokens=1*delims=:" %%a in ('findstr /n $ "%tfileB%"') do set "$b%%a=%%b"&set /a countB=%%a
for /f "tokens=1*delims=:" %%a in ('findstr /n $ "%tfileC%"') do set "$c%%a=%%b"&set /a countC=%%a
if "%countA%"=="%countB%" (echo %countA% line(s^) found in %tfileA% and %tfileB%.) else echo Line mismatch: %tfileA%:%countA% - %tfileB%:%countB%&goto:eof
if "%countA%"=="%countC%" (echo %countA% line(s^) found in %tfileC%.) else echo Line mismatch: %tfileA%:%countA% - %tfileC%:%countC%&goto:eof
SETLOCAL ENABLEDELAYEDEXPANSION
for /l %%a in (1 1 %countA%) do (
echo copy "!$a%%a!" "!$b%%a!"
echo ^>"!$b%%a!\!$a%%a!" echo(!$c%%a!
)
endlocal
output is:
3 line(s) found in K:\file_sync_diff\FileNameList.txt and K:\file_sync_diff\DirectoryNames.txt.
3 line(s) found in K:\file_sync_diff\FileDumpText.txt.
copy "red" "K:\file_sync_diff\cat"
>"K:\file_sync_diff\cat\red" echo(more text 1
copy "orange" "K:\file_sync_diff\dog"
>"K:\file_sync_diff\dog\orange" echo(more text 2
copy "purple" "K:\file_sync_diff\333"
>"K:\file_sync_diff\333\purple" echo(more text 3
I was successful using the following code, but with one issue. I get a ".txt" file now. This is caused by a return charter in the FileNameList.txt file but if their is no return after the last file name in the FileNameList.txt then that file doesn't get copied.
So I just need a line of code to delete ".txt" and not any other file with an actual name.txt Any help with that would be nice.
My current Code
#echo off
echo.
REM check if file is there
if exist F:\file_sync_diff\FileNameList.txt goto Label 1
REM display error
echo Can not find the File Name List
echo.
echo.
Pause
goto :eof
:Label 1
REM display that the file in the last check was found
echo found FileNameList.txt
REM check if file is there
if exist F:\file_sync_diff\FileDumpText.txt goto Label 2
REM display error
echo Can not find File Dump Text File
echo.
echo.
Pause
goto :eof
:Label 2
REM display that the file in the last check was found
echo found FileDumpText.txt
REM check if file is there
if exist F:\file_sync_diff\DirectoryNames.txt goto Label 3
REM display error
echo Can not find Directory Names Text File
echo.
echo.
Pause
goto :eof
:Label 3
REM display that the file in the last check was found
echo found DirectoryNames.txt
REM for loop to filter through every line in a file
echo.
for /f %%i in (F:\file_sync_diff\FileNameList.txt) do call :Sub %%i
goto Label 4
goto :eof
:Label 4
REM thanks to Endoro#StackOverFlow
#ECHO OFF &SETLOCAL
REM set associative arrays
set "tfileA=F:\file_sync_diff\FileNameList.txt"
set "tfileB=F:\file_sync_diff\DirectoryNames.txt"
REM setup for loops
for /f "tokens=1*delims=:" %%a in ('findstr /n $ "%tfileA%"') do set "$a%%a=%%b"&set /a countA=%%a
for /f "tokens=1*delims=:" %%a in ('findstr /n $ "%tfileB%"') do set "$b%%a=%%b"&set /a countB=%%a
SETLOCAL ENABLEDELAYEDEXPANSION
for /l %%a in (1 1 %countA%) do (
echo.
move "!$a%%a!.txt" "!$b%%a!"
echo.
echo ^>"!$b%%a!\!$a%%a!" echo(!$c%%a!)
echo.
endlocal
:Sub
echo Writing %1
REM copy the contents of FileDumpText.txt to the file that was passed in the last method
type F:\file_sync_diff\FileDumpText.txt >> %1.txt
goto :eof

Read a variable from a text file

I'm trying to create a password prompt which compares the user input to information in a text file (the password is saved in the .txt file).
I've tried to work with information provided to me through the command prompt and and this website but I just can't get it to work, probably because i don't have sufficient experience as I'm rather new to advanced batch coding.
This is what I've come up with so far, the name of the text file is Q47.txt and in it is just the word "hello" until I can get this to work:
#echo off
:a
cls
SetLocal EnableDelayedExpansion
set content=
for /F "delims=" %%i in (Q47.txt) do set content=!content! %%i
echo %content%
EndLocal
echo Enter password to continue:
set /p "VAR=>"
if "%VAR%" == "%content%" (
goto begin
)
echo Incorrect, please try again.
pause >nul
goto a
:begin
cls
echo Welcome
pause >nul
Please can you tell me where I've gone wrong.
I'd also like to know how to eliminate the space before the variable.
You might try this:
#ECHO OFF &SETLOCAL
:a
set "content="
for /F "tokens=*" %%i in (Q47.txt) do set "content=%%i"
echo "%content%"
echo Enter password to continue:
set /p "VAR=>"
if "%VAR%" == "%content%" goto begin
echo Incorrect, please try again.
pause >nul
goto a
:begin
cls
echo Welcome
pause >nul
Read the file into a variable like this:
set /p content=<"C:\path\to\Q47.txt"

Creating a simple finger application with batch

I would like to make a simple batch application that does two things.
Asks the user to input a name, example "vega"
Runs "finger vega#mail.example.com" and displays the output of that command.
The following does the first thing, but I am not able to output the result from the finger.
#ECHO OFF
:begin
echo Enter the name of the user you are looking for:
set INPUT=
set /P INPUT=Name: %=%
finger -l %INPUT%#mail.example.com
pause
GOTO begin
Something like this maybe.
#echo off
setlocal
set INTERVAL=10
echo Enter the name of the user you are looking for:
set /P INPUT=
echo INPUT=%INPUT%
echo Name: %INPUT%
:LOOP
for /F "usebackq tokens=*" %%a IN (`finger -l %INPUT%#mail.example.com`) DO set OUTPUT=%%a
echo OUTPUT=%OUTPUT%
if "%OUTPUT%"=="something" (goto LOOPEND)
call :SLEEP %INTERVAL%
goto LOOP
:LOOPEND
goto :eof
:: -------------- Sleep function -------------------
:SLEEP
set /a SECS=%1
set /a SECS+=1
ping 127.0.0.1 -n %SECS% -w 1000 > nul
goto :eof

Resources