我有一个批处理文件,它接受操作模式作为参数,并按照它的特定顺序运行几个命令,我想知道除了有大量的IF语句之外,还有其他方法来处理这个批处理文件吗?
这不是真正的代码,只是显示了流程。
Get MODE as Parameter
If MODE=TYPE1 or MODE=TYPE2 then
Run Command A
endif
If MODE=TYPE1 or MODE=TYPE3 then
Run Command B
endif
If MODE=TYPE3 then
Run Command C
endif发布于 2014-06-11 11:10:00
@echo off
setlocal enableextensions
set "MODE=%~1"
set "WHENMODE=call :testCase "%MODE%" "
%WHENMODE% TYPE1 TYPE2 && (
echo Run command A
)
%WHENMODE% TYPE1 TYPE3 && (
echo Run command B
)
%WHENMODE% TYPE3 && (
echo Run command C
)
endlocal
exit /b
:testCase value test1 test2 ... testn
if "%~2"=="" exit /b 1
if "%~1"=="%~2" exit /b 0
shift /2 & goto %0%WHENMODE%的定义仅仅是审美的。没有装饰的相同代码
@echo off
setlocal enableextensions
set "MODE=%~1"
call :testCase "%MODE%" TYPE1 TYPE2 && echo Run command A
call :testCase "%MODE%" TYPE1 TYPE3 && echo Run command B
call :testCase "%MODE%" TYPE3 && echo Run command C
endlocal
exit /b
:testCase value test1 test2 ... testn
if "%~2"=="" exit /b 1
if "%~1"=="%~2" exit /b 0
shift /2 & goto %0发布于 2014-06-11 11:55:21
首先,我认为谨慎的做法是展示如何处理IF语句。批处理IF不支持或逻辑。下面模拟OR:
@echo off
setlocal enableDelayedExpansion
set "mode=%~1"
set "aModes= TYPE1 TYPE2 "
set "bModes= TYPE1 TYPE3 "
set "cModes= TYPE3 "
if "!aModes:%mode%=!" neq "!aModes!" echo command A
if "!bModes:%mode%=!" neq "!bModes!" echo command B
if "!cModes:%mode%=!" neq "!cModes!" echo command C现在寻找可能替代IF的方法。
( 1)我能想到的一件半实用的事情是用这种模式作为标签,但我不喜欢它。不必要的调用使用速度可能会大大减慢。您必须确保模式值被控制,否则您将收到难看的错误消息。此外,由于相同的模式运行多个命令,所以这些命令在代码中被复制。
@echo off
setlocal
set "mode=%~1"
call :%MODE%
:: remainder of logic
exit /b
:TYPE1
echo command A
echo command B
exit /b
:TYPE2
echo command A
exit /b
:TYPE3
echo command B
echo command C
exit /b如果命令A和/或B和/或C是一个复杂的命令块,那么可以将它们变成自己的标记子例程,并在适当的情况下生成CALLed。这将防止复杂逻辑的复制。
2)另一种可能是带有条件命令执行的FINDSTR,但这比如果执行要慢,而且比较尴尬。唯一的优点是它不需要额外的变量来实现OR逻辑。
@echo off
setlocal
set "mode=%~1"
echo %mode%|>nul findstr "TYPE1 TYPE2" && echo command A
echo %mode%|>nul findstr "TYPE1 TYPE3" && echo command B
echo %mode%|>nul findstr "TYPE3" && echo command C请注意,如果您的模式类似于BC和ABCD,那么上面的模式将无法工作,因为BC包含在ABCD中。可以通过引入一些括号来处理这一问题。
@echo off
setlocal
set "mode=%~1"
echo {%mode%}|>nul findstr "{TYPE1} {TYPE2}" && echo command A
echo {%mode%}|>nul findstr "{TYPE1} {TYPE3}" && echo command B
echo {%mode%}|>nul findstr "{TYPE3}" && echo command C最后,您可以使用MC ND的简单宏的想法,使上述看起来更优雅一点。
@echo off
setlocal
set "mode=%~1"
set "whenMode=echo {%mode%}|>nul findstr"
%whenMode% "{TYPE1} {TYPE2}" && echo command A
%whenMode% "{TYPE1} {TYPE3}" && echo command B
%whenMode% "{TYPE3}" && echo command C3)您可以非常喜欢并使用一种先进的带参数的批处理宏技术。这是一个对带有参数的批处理宏的技术和开发的良好入门。
设置宏需要大量的神秘代码,但是一旦定义了宏,它就非常容易使用,而且速度非常快。最好的部分是它可以用于任何变量。在下面的示例中,我将它与MODE1和MODE2一起使用。
@echo off
setlocal disableDelayedExpansion
set "mode1=%~1"
set "mode2=%~2"
:: define LF as a Line Feed (newline) character
set ^"LF=^
^" Above empty line is required - do not remove
:: define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:: define a when macro that takes arguments
set when=%\n%
for %%# in (1 2) do if %%#==2 (setlocal enableDelayedExpansion^&for /f "tokens=1*" %%1 in ("!args!") do (%\n%
set "test= %%~2 "%\n%
for /f %%M in ("!%%1!") do (%\n%
if "!test:%%M=!" neq "!test!" (%\n%
endlocal%\n%
endlocal%\n%
(call )%\n%
) else (%\n%
endlocal%\n%
endlocal%\n%
(call)%\n%
)%\n%
)%\n%
)) else setlocal^&set args=
:: ------- End of Initialization ---------------------
(%when% mode1 "TYPE1 TYPE2") && echo command A
(%when% mode1 "TYPE1 TYPE3") && echo command B
(%when% mode1 "TYPE3") && echo command C
(%when% mode2 "TYPE1 TYPE2") && echo command X
(%when% mode2 "TYPE1 TYPE3") && echo command Y
(%when% mode2 "TYPE3") && echo command Z发布于 2014-06-11 14:53:03
我认为解决这个问题最清晰、最快的方法就是通过数组。
@echo off
setlocal EnableDelayedExpansion
rem Define the array of equivalences from MODE values vs Command
set numCommands=0
for %%a in ("TYPE1|TYPE2=Command A"
"TYPE1|TYPE3=Command B"
"TYPE3=Command C") do (
set /A numCommands+=1
set "command[!numCommands!]=%%~a"
)
rem Get MODE as parameter:
set "MODE=%~1"
rem Execute the commands in order
for /L %%i in (1,1,%numCommands%) do (
for /F "tokens=1,2 delims==" %%a in ("!command[%%i]!") do (
set "options=|%%a|"
if "!options:|%MODE%|=!" neq "!options!" ECHO Run: %%b
)
)编辑:或以更短的方式编辑,没有数组:
@echo off
setlocal EnableDelayedExpansion
set "MODE=%~1"
for %%i in ("TYPE1|TYPE2=Command A"
"TYPE1|TYPE3=Command B"
"TYPE3=Command C") do (
for /F "tokens=1,2 delims==" %%a in (%%i) do (
set "options=|%%a|"
if "!options:|%MODE%|=!" neq "!options!" ECHO Run: %%b
)
)https://stackoverflow.com/questions/24160567
复制相似问题