Sorry, i've done some silly error:
I've edited my source above so it (hopefully) should work now.
The search phrase "/C:"set\[1\].*;%~1;"" (fixed) is a regular expression to search the string "set[1]<any characters>;<argument 1>;" within the "set set[" command output.
"call" sets the errorlevel to 1, and "call;" sets it to 0.
findstr is executed in "for/F" so the output is passed to %%a (""~a without doublequotes if any) based on for/F options.
penpen
One-liners for logical OR operator
Moderator: DosItHelp
Re: One-liners for logical OR operator
I do typos a lot more often. This one does work great in a quick test, including when an argument is a phrase like "Miami Beach".
While it works, I can't grasp the logic of this code. It seems to do call; (i.e. assign errorlevel to 1) regardless of the %%a value?
While it works, I can't grasp the logic of this code. It seems to do call; (i.e. assign errorlevel to 1) regardless of the %%a value?
Re: One-liners for logical OR operator
The idea behind this algorithm is very simple:
After initializing the errorlevel to 0 we use "findstr" to search for argument i in set[i] (i in[1:3]), printing lines only that do not contain a match (option "/v").
In other words if findstr produces output, then there is an argument that is invalid (not part of the associated set).
In that case we the errorlevel is set to 1.
Maybe here it is easier to see:
(Note that set[3] contains the so called "empty word" (by using ";;", so it finds a match on no argument.)
penpen
After initializing the errorlevel to 0 we use "findstr" to search for argument i in set[i] (i in[1:3]), printing lines only that do not contain a match (option "/v").
In other words if findstr produces output, then there is an argument that is invalid (not part of the associated set).
In that case we the errorlevel is set to 1.
Maybe here it is easier to see:
Code: Select all
@echo off
setlocal enableExtensions enableDelayedExpansion
set "set[1]=;York;London;Brussels;"
set "set[2]=;1;2;3;"
set "set[3]=;;\;/;&;&&;|;||;(;);[;];{;};^^;^!;';+;-;,;`;~;^";^";:;"
for /F "tokens=1 delims=:" %%a in ('set set[ ^|findstr /V /N /B /R /C:"set\[1\].*;%~1;" /C:"set\[2\].*;%~2;" /C:"set\[3\].*;%~3;"') do echo Argument %%~a is no element of {!set[%%~a]:~1,-1!}.
endlocal
Code: Select all
Z:\>test Paris
Argument 1 is no element of {York;London;Brussels}.
Argument 2 is no element of {1;2;3}.
penpen
Re: One-liners for logical OR operator
Ops! I just realized that my original code did not check for empty arguments! The fix is to move a slash to another place and change a "%%a" by "!arg:~1" this way:
I already edited the original code above. With this change, each empty argument is reported.
Antonio
PS - I just want to note that in my method you just need to add one line of code for each argument, but in penpen's method it is necessary to also add a /C switch in the findstr line, so this line becomes larger...
Code: Select all
for /L %%i in (1,1,4) do call set "arg=%%%%i" & for /F %%a in ("!arg!") do if "!set[%%i]:/%%a/=!" equ "!set[%%i]!" set "error=!error!, #%%i (%%a)"
^ ^ ^^^
Insert the slash here: | Remove this slash: | Change %%a by !arg:~1! here: |||
I already edited the original code above. With this change, each empty argument is reported.
Antonio
PS - I just want to note that in my method you just need to add one line of code for each argument, but in penpen's method it is necessary to also add a /C switch in the findstr line, so this line becomes larger...
Re: One-liners for logical OR operator
Aacini wrote:I just want to note that in my method you just need to add one line of code for each argument...
Thanks for clarification. Both methods work great and have certain advantages each. I couldn't find such solutions anywhere on the web. Analyzing user input and batch arguments usually presents serious challenge for inexperienced coders, so such complete solutions presented in a very compact and efficient code provide outstanding guidance to many folks on this typical issue.
Let me also think on how to complicate the original question, thus attempting to make the solution even more universal. I can tell you for sure, key elements of any my batch code contain in some form solutions suggested on this forum by Aacini, penpen, aGerman and other experts, and in most cases they replace tons of trivial code, plus enable re-use in various scenarios by providing in-depth clarification on how it works.