Expanding variables in IF statements in batch - batch-file

So I need to see if a string contains something. I was thinking, you know how you can do set VAR=%VAR:-=_% to target certain things inside the variable and change them with the set command. Well, is there a way I can do this with "IF" statements?.
Example of what it might look like:
if %VAR%==%VAR:word% echo yes
This command doesn't actually work but if it did, it would look to see if %VAR% contains "word" anywhere in it.

You're very close, but you've only got half of a valid string substitution command, which isn't causing a syntax error, but it is causing a flow in the logic: right now you're comparing %VAR% to a variable that the interpreter can't access.
If you use string substitution to remove the word you're looking for and then compare that to the original variable, you can use an if not statement to determine if the variable was updated by the substitution.
if not "%var%"=="%var:word=%" echo yes

Related

escaping the special characters without knowing the position batch

I have a requirement to execute a batch file with the arguments. the problem occuring here is I am not sure what special characters and at what place it can occur. I have gone through possibly all the answers here but still unable to fix the issue. Any help is appreciated.
Command that i am trying to run within the batch file
CALL E:\myscript.bat -run e:\param -password %PASSWORD%
where PASSWORD is the variable storing the password and it can be having any special characters at any position.
Maybe I understood your question, it would be:
You want to identify, without having to have specific argument
positions, what each argument represents.
Or:
You want to find a solution to handle the arguments so that they do
not result in errors because they contain special characters
Anyway, I will answer both.
You have some alternatives for doing so, some may be more ideal than others depending on how you are handling your code and its purpose.
In case you identify the arguments and what they represent, you can:
set args=%*
Some things may help you make your code stable while using an wildcard without its effect. Like:
set "args=%args:&=^&"
But the most important thing is to keep the code without quotes. In fact, the use of CALL is not necessary if you are not doing it within a script.
set "args=%args:"=%
The next thing to do is to identify the parameters. We can do this both in a crude way and in a simpler way, which would be defining each argument with its own variable, such as: arg1=%1, arg2=%2...
You can now pass all parameters into a treatment and reconstruction session.
Assuming you want to identify -password:
---during a FOR loop to catch and make the same processes at every arg---
(which I can only guess because you didn’t show the code or anything like that)
if "!arg[%%x]:~0,1!" equ "-" (
if "!arg[%%x]:-=!" equ "password" set /a x=%%x+1&set "password=!arg[%x%]!"
if "!arg[%%x]:-=!" equ "run" set /a x=%%x+1&set "run=!arg[%x%]!"
...
)
Obviously there are some things that can improve in this code, but you have shown almost nothing for us to use as a reference to answer, so that's all I can do.
Hope this helps,
K.

cmd batch variable behavior is unintuitive

I'm using windows 10, running batch files through the command prompt window.
I can make things work, but I don't know why it works or why I can't do certain things:
set "file_list=a1 a2"
for %%a in (%file_list%) do (
echo %%a.py
)
This little piece of code works. I can build on it, BUT
Q1: I want to change the variable %%a to %%filename... but that doesn't work! I wondered if maybe filename were reserved, so I tried %%fname .
In this case I get the error:
%fname was unexpected at this time.
I can do a set fromm the command line and use a descriptive variable name, but it doesn't seem to work when looping. (I did it with the %file_list% variable above!) So how come I can only use a single character for a loop variable? Is there some way around that?
Q1a. This makes me think that the loop index variable is a different kind of variable that the ones in set commands. Is that correct? If so, is there a link that clearly and concisely explains the difference?
Q2. I notice the loop index variable is %%a, instead of a or %a or %a% . I never would have guessed this. The web sites I've looked at have just said, do this. But I can't see any explanation of why, except that the first percent is an escape. Okay. That doesn't really explain anything. It just means "this is how you do it." The error message when I use one percent sign is interesting.
set "file_list=a1 a2"
for %a in (%file_list%) do (
echo %a.py
)
"file_list) was unexpected at this time."
So I can vaguely see that maybe something isn't being escaped correctly. Why does that % in the %a need to be escaped, so it becomes %%a ?
A for meta-variable must consist of % (in Command Prompt) or %% (in a batch file) and a single character (case-sensitive letter), like %a or %%a. You cannot define %filename or %%filename.
Loop variables only exist within the respective for loop. Do not confuse such loop variables with normal environment variables, like %TEMP%, for example, which are available globally.
There are these things marked by %-signs:
%-escaping (only applicable for batch files), so %% denotes one literal %-sign;
command line arguments/parameters (only applicable for batch files, obviously), like %1;
immediately expanded environment variables*, like %TEMP%;
for meta-variables, like %a (in Command Prompt) or %%a (in batch files), which are specific to the for command, so they do not exist outside of the related loop context;
%-escaping (1.) happens before expanding for meta-variables (4.), hence actually the for command receives a loop variable like %a.
Then environment variables (3.) are treated differently in Command Prompt and in batch files: the former keeps undefined variables literally, the latter removes them.
The detailed parsing rules can be found in this post, which have been implemented by Microsoft (or IBM?) that way in order to be able to distinguish between the different %-things, so at the end it was their decision, therefore you have to ask them for the exact reason…
*) There is also something like delayed environment variable expansion, but this uses !-signs to mark the variables, like !TEMP!, and this is something that happens after all the %-sign expressions have been parsed.

IF command not working when using 'NOT or '==' to use CALL and use SET for setting a variable

I'm creating a simple program that will echo variables from SET /p strings into a nice, neat list. However, I am having trouble creating 2 working IF statements, one using NOT, and one using == to detect if one of my variables, %pwad%, is empty, or contains values. I want to use what the IF statement returns to set variable %finalpwad% to either "No pwad detected" or %pwad%.
How should I properly write this statement? Where might I need corrections, fixing the IF statements or maybe even the part where it sets %pwad% to %finalpwad%?
I have already tried fixing my call part and what they call from, but to no avail. I'm almost sure this is an IF statement issue, as I'm not too good with them, and always struggle reading the notes about the command from IF /?.
Here's a snippet of my code and the source of the problem I am having:
set /p pwad=Set a pwad (or none):
if %pwad% NOT [] call :yespwad & pause
if %pwad% == [] :nopwad & pause
:nopwad
set finalpwad=No pwad detected
goto :printout
:yespwad
set finalpwad=%pwad%
goto :printout
I expect the output to continue onto :printout, where it echoes all the variables the user enters, but it instead exits the program, and makes it so I can't find out whether it properly read my IF NOT or IF == statements. I rudimentarily added pauses to snuff out the problem and see where the source was, and I concluded it must the IF statements.
The help file clearly shows the proper syntax for comparing strings.
IF [NOT] string1==string2 command
It is recommended that you use quotes as well when comparing strings.
IF "string1"=="string2" command
IF comparisons are literal. Each side of the comparison has to match. Using brackets does not check for an empty string.
There also is an option to check if a variable is defined.
IF DEFINED VAR command
Looking at your logic you could essentially do this:
#echo off
set /p "pwad=Set a pwad (or none): "
IF DEFINED pwad (
set "finalpwad=%pwad%"
) ELSE (
set "finalpwad=No pwad detected"
)

Dynamic variable name in cmd.exe w/ command extensions

I see this is a common theme, but I believe I have a unique problem.
I want to use this technique of variable expansion, where you can use the ":" to substitute strings in expanded result (the "&" part being a trick to force command execution)
echo %PATH:;=&echo.%
, but like this:
set VAR=PATH
set DELIM=;
set SUBST=echo.
echo %VAR:%DELIM%=&%SUBST%%
Well, I hope you get the point. The above is not valid code.
Anyone has a clue?
The example in the question should be considered generic, and not to be taken literally. The question is can it be done and exactly how?

Batch File: Output variable to text file

I would like to output a variable to a text file. I have done this in my code, but I have one output within an if statement that I can't get to work.
if not exist "%TuningLog%" (
set Title=Tuning Parameters Saving Log
set LogTitle=--------- %Title% ---------
echo %LogTitle%>> "%TuningLog%"
)
All its supposed to do is check first for the existense of a log file and if it doesn't exist then I want to in the first instance append a title.
But all I get in the log file is " echo is off." If I don't use a variable and just place text there then it works fine.
Can anybody spot the problem? Thanks for reading and for any help!
UPDATE:
I changed my code to. I don't know much about delayed expansion, but I tried this and it happened to work...
if not exist "%TuningLog%" (
setlocal enabledelayedexpansion
set Title=Tuning Parameters Saving Log
set LogTitle=--------- !Title! ---------
echo !LogTitle!>> "!TuningLog!"
endlocal
)
If anyone can provide a reason as to why the first attempt didn't work and this did, then please inform this thread for the purposes of learning. Thank you!
because or early expansion. your variable gets replaced with its value at the moment the block starts. at this time, it is still undefined and thus empty. if you have echo on, you can watch this happening on screen. if you enable delayed expansion, as you did in your second example, it gets only expanded at the moment it is used, so it works as you expect variables to work in "real" programming languages.
EnableDelayedExpansion
causes Variables to be expanded in simple language it causes the system to treat the value of variable and not the variable name itself

Resources