Using Set /p command with a for loop - batch-file

I'm working on a simple batch file to save a text file for each JPG. The content of the txt file are input by user using set /p. For some reason when i used set /p with the for loop, the txt file did not show value input by user (it only shows: "ECHO is on").Any help would be highly appreciated! Thanks.
for %%Q in (*v.JPG) do (
set /p meas= "enter value "
echo %meas%>"%%~nQ.txt"
)
pause

Magoo is right, Thank you! I had to use Enable delayed expansion, and then referto variables as !variable! and not %variable%. Unfortunately, there isn't documentation on Microsoft website on this issue, at least not on the 'set' command webpage.

for %%Q in (v*.jpg) do ( set /p meas="enter value " && echo !meas! > %%~nQ.txt)
I tested this in just a cmd prompt but should work in a batch as well.
This will create a new file named <filename>.jpg.txt and will contain the value the user entered.
The key is to add && between set /p and echo.

Related

set /p is not working as expected

I am trying to create the interactive bat file which ask for the folder details it is able to take the userchoice but after that it is not able to set the folder path given by useri.e. it takes the path till Desktop only.Below is my code for the same:
#echo off
set /p UserInfo= "Do you have abc software(y/n)? "
echo %UserInfo% // here it is working as expected
IF %UserInfo%==y (
echo "Reply is true-----"
set /p Path= "Please enter path for abc directory? "
echo %Path% //but here it takes the path till the desktop only(C:\user\username\Desktop)
CD %Path%
dir
set /p Path1= "Please enter path1 directory path provided in package? "
echo %Path1% //but here it takes the path till the desktop only(C:\user\username\Desktop)
CD %Path1%
)
IF %UserInfo%==n (
echo "Reply is False**************"
)
pause
How to read the folder directive?
Hmm.. Please use the search bar as user Magoo, LotPings said.
Also, Stephan & Squashman mentioned, do not set a variable with the name path because there is a internal variable named path. If you rename it, other programs may not work properly.
What's DelayedExpansion?
When batch files are run, cmd process them line by line. The entire if statement get processed at once. That's why the variable are un-set.
Since we want cmd to process those variable at run-time, we will need to tell it to do so, by adding setlocal enableDelayedExpansion. This enables run-time variable expansion. To disable, just change enable to disable.
You may want to add it like so:
#echo off
setlocal enableDelayedExpansion
rem your code follows...
How To Make Variable Get Processed Run-Time?
Simply change %var% to !var!.
Please note that for loop metavariable %%n cannot be changed to !!n, since itself already implicated a delayed expansion.
Command-line arguments %n cannot be changed to !n. You may want to do this instead:
if "%var%"=="abc" (
set variable=%1
echo !variable!
)
SET /P Code Injection Cause Security Issue?!
If the input of %Userinput% is a==a format D:\ && echo, cmd sees:
if a==a
do format D:\
do echo ==y (
Which... formats your D drive. Adding quotes like if "%var%"=="abc" won't help since user can just escape the quote and execute the commands.
See here for more info.
SET /P Alternatives
You may want to consider CHOICE for single letter choice. It's command syntax is like so:
choice /c choices /n /cs /t timeout /d default_choice /m prompt
/n hides the list of options, letting /m to display it's own prompt
/cs == case-insensitive.
PATH Variable
Again mentioned above, PATH is a internal variable used by Windows and other programs. Mis-setting it may cause some Windows functions or programs to stop functioning properly.
Instead, use another variable name like programPath.

Why is the string of a variable redirected to a file with trailing space and not correct displayed after read from file?

I'm trying to work with batch, but I'm having some bugs that I didn't have before making similar applications.
First issue:
I'm using set /p to prompt for a string, then I save it to a file using
ECHO Myvar>"%systemroot%\name.ini"
That works fine, but when I open the file name.ini there is a space after the string I typed. I built already a batch in the past using this and it didn't happen.
Second issue:
When I load the file to string, it doesn't work. Something happens to the string that if I try to output it using
ECHO %Myvar%
the output is ECHO is off. As I said before, I used this once already in a different batch file and it worked fine.
Example code:
#ECHO OFF
if not exist "%systemroot%\asd.ini" (
set /p asd= COMR:
ECHO %asd%>"%systemroot%\asd.ini"
REM Save the string to a file
) else (
set /p asd=<"%systemroot%\asd.ini"
REM Read the string
ECHO %asd%
pause
)
P.S: I already tried using SETLOCAL EnableDelayedExpansion, but it still doesn't work as expected.
setlocal enabledelayedexpansion
if not exist "%systemroot%\asd.ini" (
set /p asd= COMR:
ECHO !asd!>"%systemroot%\asd.ini"
REM Save the string to a file
) else (
set /p asd=<"%systemroot%\asd.ini"
REM Read the string
ECHO !asd!
)
pause
Stuff in brackets are treated as one line.
I removed Echo Off - hiding messages is not a good idea when you have a problem.

Remember username in batch file

I have made a litle batch file,
where you need to insert your account name of your computer.
I'm wondering if you could maybe write the account name to a text file,
so the program could remember it for next time you open it.
and don't have do enter it twice on the same computer.
What about this?
#echo off
echo Prevous value is:
echo %mysetting%
echo.
set /p input="Enter new value: "
setx mysetting %input%
pause
Save this as .bat and run twice to see the persistence.
setlocal EnableDelayedExpansion
if exist username.txt (
REM Read from text file:
set /p "user="<username.txt
) else (
REM Read from keyboard:
set /p "user=Enter your username: "
REM Write to text file:
echo !user!>username.txt
)

Trying to create text file using user-input with Batch

echo.
set /p textfileName=What would you like the file to be named?
echo.
echo On the line below, write what text you would like the file to contain:
echo.
set /p textfileContents=
echo %textfileWrite% >> %textfileWriteName%.txt
echo.
echo Your file has been created and is in the same directory as this batch file.
echo It is named %textfilename%.txt
echo.
goto inputCommand
Whenever I try to use this code, it comes up with "Echo is off" (from #echo off previously in the file) but not what the user inputted. Then, if I run it again in the same instance, it will create the previous file but not the one I just told it to create.
I've tried having > and it didn't work, >> didn't work either.
I think you have a few problems going on here. First, you mentioned #echo, but looking at your code, you're just using echo.
Also, I think there's some confusion with your variables. You capture the user's filename into textfilename, but then write to textfileWriteName. You capture the user's file contents in textfileContents, but then write textfileWrite to the file.
Finally, you specify a goto label that doesn't exist. Maybe this is part of a larger batch file that you just partially copied?
Anyhoo, I think this is along the lines of what you intended:
#echo off
set /p textfileName=What would you like the file to be named?
#echo On the line below, write what text you would like the file to contain:
set /p textfileContents=
#echo %textfileContents% > %textfileName%.txt
#echo Your file has been created and is in the same directory as this batch file.
#echo It is named %textfilename%.txt
you have serious space issues in your variables " text filename and text contents"
avoid spaces in your variables or if you must use more than one word in your variable use symbols to separate the strings .. the code below should work fine
#echo off
: main_menu
echo.
echo.
set /p notf=name of text file :
set / p cof=contents of file :
echo %cof%>>"%notf%.txt"
echo %notf% text file was successfuly created...
echo.
echo.
echo press any key to return to main menu
pause>null
cls
goto main_menu

Is there anyway to have preset data for user input in a batch file?

So basically I have a batch file that requires alot of user input. I was wondering if it was possible to have any filler data already present when the question is asked, and if the user needs to change something, they can go edit that data. For example
And then the user enter their first and last name.
But is it possible to start with a default name that the user can go back and edit if they need?
This probably isn't necessary, But this is the code I use for the user input.
Set /p "Author=Please enter your name: "
And I understand for the Author it wouldn't make much sense to have preset data, but there are other instances where it would be useful for me to do this. Is it possible?
nearly impossible to edit a preset value with pure batch, but you can easily give a default value (works, because set /p is not touching the variable, if input is empty)
set "author=First Last"
set /p "author=Enter name or press [ENTER] for default [%author%]: "
echo %author%
The method below have the inconvenience that the screen must be cleared before the user enter the data, but I am working trying to solve this point:
EDIT: I fixed the detail of the first version
#if (#CodeSection == #Batch) #then
#echo off
rem Enter the prefill value
CScript //nologo //E:JScript "%~F0" "First Last"
rem Read the variable
echo -----------------------------------------------------------
set /P "Author=Please enter your name: "
echo Author=%Author%
goto :EOF
#end
WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));
For further details, see this post.
You can set the var first and then prompt the user only if it's not defined like so:
set Author=First Last
if not defined Author set /p "Author=Please enter your name: "
You can also do this backwards where you can define a value if the user didn't define it, like so:
set /p "Author=Please enter your name: "
if not defined Author set Author=First Last
There Is another way yet to achieve this. It uses vbs script to get input and assign it to a variable, -The script can be created within and called from .bat files.
I developed this method as an alternative to accepting user input from set /p in order to validate input and prevent setting of variables with spaces or special characters.
*Validation methods omitted as does not relate to the question
Best method is to have the script generator as a secondary .bat file that you can call, as it allows for a lot of versatility regarding the information the vbs input box conveys, as well as being able to be used in any circumstance within one or more .bat files you want to be able to control input defaults with.
In your main program, when Preparing to get input-
REM Define title:
Set inputtitle=The title you want the input box to have
REM Declare variable to be assigned:
Set variableforinput=VariableName
REM Define the default Variable Value:
Set defaultinput=VariableName's Desired Default Value
REM getting the Input:
CALL "inputscript.bat" %inputtitle% %variableforinput% %defaultinput%
inputscript.bat:
#echo off
SET inputtitle=%~1
SET variableforinput=%~2
SET defaultinput=%~3
SET %variableforinput%=
SET input=
:main
REM exit and cleanup once variable is successfully defined
IF DEFINED input GOTO return
REM this creates then starts the VBS input box, storing input to a text file.
(
ECHO Dim objFSO 'File System Object
ECHO Set objFSO = CreateObject("Scripting.FileSystemObject"^)
ECHO Dim objTS 'Text Stream Object
ECHO Const ForWriting = 2
ECHO Set objTS = objFSO.OpenTextFile("%userprofile%\getinput.txt", ForWriting,
True^)
ECHO objTS.Write(InputBox("Please enter %variableforinput% to continue.","%inputtitle%","%defaultinput%",0,0^)^)
ECHO objTS.Close(^)
ECHO Set bjFSO = Nothing 'Destroy the object.
ECHO Set objTS = Nothing 'Destroy the object.
) >GetInput.vbs
START GetInput.vbs
REM a pause that allows time for the input to be entered and stored is required.
cls
ECHO (N)ext
CHOICE /T 20 /C nz /N /D n >nul
IF ERRORLEVEL ==2 GOTO main
IF ERRORLEVEL ==1 GOTO loadinput
:loadinput
IF NOT EXIST "%userprofile%\getinput.txt" GOTO invInput
<%userprofile%\getinput.txt (
SET /P input=
)
IF NOT DEFINED input GOTO invInput
REM opportunity for other validation of input before returning to main.
GOTO main
:invInput
SET input=
IF EXIST "GetInput.vbs" (
DEL /Q "GetInput.vbs"
)
REM ends the vbs script ready for the next attempt to provide input
taskkill /pid WScript.exe /T >nul
Timeout 1 >nul
GOTO main
REM assigns the input value to the variable name being set in Your Main program.
:return
SET %variableforinput%=%input%
SET input=
IF EXIST "%userprofile%\getinput.txt" (
DEL /Q "%userprofile%\getinput.txt"
)
IF EXIST "GetInput.vbs" (
DEL /Q "GetInput.vbs"
)
GOTO :EOF
I wrote an open-source Windows console program called editenv that replaces my older editv32/editv64/readline.exe utilities:
https://github.com/Bill-Stewart/editenv
Basically, editenv lets you interactively edit the value of an environment variable. One of my common use cases is to edit the Path environment variable for the current process:
editenv Path
editenv also provides the following convenience features:
--maskinput allows you to hide the typed input (note that this feature does not provide any encryption or security)
--allowedchars and --disallowchars allow you to specify which characters are allowed for input
--minlength and --maxlength let you choose a minimum and maximum length of the input string
--timeout lets you specify a timeout after which input is entered automatically
The most recent binaries are available here:
https://github.com/Bill-Stewart/editenv/releases
askingFile.cmd < response.txt
Take the input to the batch from the indicated file, one line per answer

Resources