Есть ли способ записать условный оператор IF OR IF в пакетном файле Windows?
Например:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Есть ли способ записать условный оператор IF OR IF в пакетном файле Windows?
Например:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Решение zmbq хорошо, но не может использоваться во всех ситуациях, например внутри блока кода, такого как цикл FOR DO (...).
Альтернативой является использование индикаторной переменной. Инициализируйте его как undefined, а затем определите его только в том случае, если выполнено одно из условий OR. Затем используйте IF DEFINED в качестве окончательного теста - нет необходимости использовать задержанное расширение.
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
Вы можете добавить логику ELSE IF, которую использует arasmussen на том основании, что она может выполнить бит быстрее, если первое условие истинно, но я никогда не беспокоюсь.
Добавление. Это дублированный вопрос с почти идентичными ответами на Использование OR в выражении IF WinXP Batch Script p >
Заключительное дополнение. Я почти забыл свой любимый метод, чтобы проверить, является ли переменная какой-либо из значений. Инициализируйте тестовую переменную, содержащую список допустимых значений, а затем используйте поиск и замену, чтобы проверить, находится ли ваша переменная в списке. Это очень быстро и использует минимальный код для произвольно длинного списка. Это требует отсроченного расширения (или трюк CALL %% VAR %%). Также тест CASE INSENSITIVE.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
Вышеуказанное может завершиться ошибкой, если VAR содержит =
, поэтому тест не является безупречным.
Если вы выполняете тест в блоке, где требуется замедленное расширение для доступа к текущему значению VAR, тогда
for ... do (
set "TEST=;val1;val2;val3;val4;val5;"
for /f %%A in (";!VAR!;") do if "!TEST:%%A=!" neq "!TEST!" (echo true) else (echo false)
)
Для таких параметров, как "delims =", могут потребоваться опции в зависимости от ожидаемых значений внутри VAR
Вышеупомянутая стратегия может быть сделана надежной даже с =
в VAR, добавив немного больше кода.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
Но теперь мы потеряли способность предоставлять предложение ELSE, если мы не добавим индикаторную переменную. Код начал выглядеть немного "уродливым", но я думаю, что это лучший эффективный надежный метод тестирования, если VAR - любое произвольное число без учета регистра параметров.
Наконец, есть более простая версия, которая, по моему мнению, немного медленнее, потому что она должна выполнять один IF для каждого значения. Aacini предоставил это решение в комментарии к принятому ответу в упомянутой выше ссылке
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A do echo true
Список значений не может включать * или? символы, а значения и %VAR%
не должны содержать кавычки. Цитаты приводят к проблемам, если %VAR%
также содержит пробелы или специальные символы, такие как ^
, &
и т.д. Еще одно ограничение этого решения заключается в том, что он не предоставляет вариант для предложения ELSE, если вы не добавите индикаторную переменную. Преимущества могут быть чувствительны к регистру или нечувствительны в зависимости от наличия или отсутствия опции IF /I
.
Я так не думаю. Просто используйте два IF и GOTO одну и ту же метку:
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't found it
GOTO end
:foundit
ECHO Found it!
:end
Спасибо за этот пост, это очень помогло мне.
Не знаю, может ли это помочь, но у меня была проблема, и благодаря вам я нашел то, что, по моему мнению, является другим способом ее решения на основе этой логической эквивалентности:
"A или B" совпадает с "not (not A, а не B)"
Таким образом:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
становится:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
Даже если этот вопрос немного старше:
Если вы хотите использовать if cond1 or cond 2
- вам не следует использовать сложные циклы или такие вещи.
Просто обеспечьте как ifs
после друг друга в сочетании с goto
- что неявное или.
//thats an implicit IF cond1 OR cond2 OR cond3
if cond1 GOTO doit
if cond2 GOTO doit
if cond3 GOTO doit
//thats our else.
GOTO end
:doit
echo "doing it"
:end
Без goto, но действие "inplace", вы можете выполнить действие 3 раза, если все условия совпадают.
В пакете нет IF <arg> OR
или ELIF
или ELSE IF
, но...
Попробуйте вставить другой IF внутри ELSE предыдущего IF.
IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
Цель может быть достигнута путем косвенного использования ИФ.
Ниже приведен пример сложного выражения, которое может быть написано достаточно сжато и логично в партии CMD, без некогерентных меток и GOTO.
Кодовые блоки между() скобками обрабатываются CMD как (жалкий) вид подоболочки. Независимо от того, какой код выхода выходит из блока, будет использоваться для определения значения true/false, которое блок играет в более крупном булевом выражении. Произвольные большие булевы выражения могут быть построены с помощью этих кодовых блоков.
Простой пример
Каждый блок имеет значение true (т.е. ERRORLEVEL = 0 после выполнения последнего оператора в блоке)/false до тех пор, пока значение всего выражения не будет определено или управление не выйдет (например, через GOTO):
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
Сложный пример
Это решает проблему, поднятую первоначально. В каждом блоке возможны несколько операторов, но в || || || выражение предпочтительнее быть кратким, чтобы оно было максимально читаемым. ^ является побегом char в пакетах CMD, и когда он помещается в конец строки, он покидает EOL и инструктирует CMD продолжить чтение текущей партии операторов на следующей строке.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
(CALL :ProcedureType1 a b) ^
|| (CALL :ProcedureType2 sgd) ^
|| (CALL :ProcedureType1 c c)
) ^
&& (
ECHO -=BINGO=-
GOTO :EOF
)
ECHO -=no bingo for you=-
GOTO :EOF
:ProcedureType1
IF "%~1" == "%~2" (EXIT /B 0) ELSE (EXIT /B 1)
GOTO :EOF (this line is decorative as it never reached)
:ProcedureType2
ECHO :ax:xa:xx:aa:|FINDSTR /I /L /C:":%~1:">nul
GOTO :EOF
Можно использовать функцию, которая вычисляет логику ИЛИ и возвращает одно значение.
@echo off
set var1=3
set var2=5
call :logic_or orResult "'%var1%'=='4'" "'%var2%'=='5'"
if %orResult%==1 (
echo At least one expression is true
) ELSE echo All expressions are false
exit /b
:logic_or <resultVar> expression1 [[expr2] ... expr-n]
SETLOCAL
set "logic_or.result=0"
set "logic_or.resultVar=%~1"
:logic_or_loop
if "%~2"=="" goto :logic_or_end
if %~2 set "logic_or.result=1"
SHIFT
goto :logic_or_loop
:logic_or_end
(
ENDLOCAL
set "%logic_or.resultVar%=%logic_or.result%"
exit /b
)
If %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)
Это для проверки того, является ли несколько переменных равными. Здесь для любой переменной.
If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)
Я просто подумал об этом сверху, если у меня голова. Я мог бы сжать его больше.
Я понимаю, что этот вопрос старый, но я хотел опубликовать альтернативное решение, если кто-то еще (например, я) нашел этот поток, имея тот же вопрос. Я смог обойти отсутствие оператора OR, повторив эту переменную и используя findstr для проверки.
for /f %%v in ('echo %var% ^| findstr /x /c:"1" /c:"2"') do (
if %errorlevel% equ 0 echo true
)
В то время как ответ dbenham довольно хорош, полагаясь на IF DEFINED
, вы можете столкнуться с множеством проблем, если переменная, которую вы проверяете, не является переменной среды. Script переменные не получают этого специального лечения.
Хотя это может показаться какой-то смехотворной недокументированной BS, выполнение простого запроса оболочки IF
с помощью IF /?
показывает, что
Условное условие DEFINED работает как EXIST, за исключением того, что требуется среда имя переменной и возвращает значение true, если переменная средаопределяется.
Что касается ответа на этот вопрос, есть ли причина не просто использовать простой флаг после серии оценок? Это кажется наиболее гибкой проверкой OR
для меня, как в отношении базовой логики и читаемости. Например:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true)
IF %some_string%=="desired result" (Set Evaluated_True=true)
IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
Очевидно, что это может быть любая условная оценка, но я просто использую несколько примеров.
Если вы хотите, чтобы все это на одной строке было написано, вы могли бы просто связать их вместе с &&
следующим образом:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true) && IF %some_string%=="desired result" (Set Evaluated_True=true) && IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
Никогда не существовало, чтобы работать.
Я использую если не существует g: xyz/what goto h: Else xcopy c: current/files g: bu/current Существуют модификаторы /a и т.д. Не знаете, какие из них. Ноутбук в магазине. И компьютер в офисе. Меня там нет.
Никогда не было пакетных файлов для работы над Windows XP
Простое "FOR" можно использовать в одной строке для использования условия "или":
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
Применительно к вашему делу:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
Понимая, что это немного старый вопрос, ответы помогли мне придумать решение для тестирования аргументов командной строки в пакетном файле; поэтому я также хотел опубликовать свое решение, если бы кто-то еще искал аналогичное решение.
Первое, что я должен отметить, это то, что у меня возникли проблемы с получением инструкций IF... ELSE для работы внутри предложения FOR... DO. Оказывается (спасибо dbenham за непреднамеренное указание этого в своих примерах) утверждение ELSE не может быть на отдельной строке от закрывающих парнеров.
Итак, вместо этого:
FOR ... DO (
IF ... (
)
ELSE (
)
)
Каким образом я предпочитаю читаемость и эстетические соображения, вы должны это сделать:
FOR ... DO (
IF ... (
) ELSE (
)
)
Теперь инструкция ELSE не возвращается как непризнанная команда.
Наконец, вот что я пытался сделать - мне захотелось передать несколько аргументов в пакетный файл в любом порядке, проигнорировав регистр, и сообщив/провалив аргументы undefined, переданные. Итак, вот мое решение...
@ECHO OFF
SET ARG1=FALSE
SET ARG2=FALSE
SET ARG3=FALSE
SET ARG4=FALSE
SET ARGS=(arg1 Arg1 ARG1 arg2 Arg2 ARG2 arg3 Arg3 ARG3)
SET ARG=
FOR %%A IN (%*) DO (
SET TRUE=
FOR %%B in %ARGS% DO (
IF [%%A] == [%%B] SET TRUE=1
)
IF DEFINED TRUE (
SET %%A=TRUE
) ELSE (
SET ARG=%%A
GOTO UNDEFINED
)
)
ECHO %ARG1%
ECHO %ARG2%
ECHO %ARG3%
ECHO %ARG4%
GOTO END
:UNDEFINED
ECHO "%ARG%" is not an acceptable argument.
GOTO END
:END
Обратите внимание, что будет отображаться только первый неудачный аргумент. Поэтому, если пользователь передает более чем один неприемлемый аргумент, им будет сообщено только о первом, пока он не будет исправлен, затем второй и т.д.