Как бы вы реализовали логические операторы в пакетных файлах DOS?
Логические операторы (and, or) в пакете DOS
Ответы (12)
Вы можете сделать and
с вложенными условиями:
if %age% geq 2 (
if %age% leq 12 (
set class=child
)
)
or:
if %age% geq 2 if %age% leq 12 set class=child
Вы можете сделать or
с отдельной переменной:
set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if "%res%"=="T" (
set state=asleep
)
set res=
или set res=1
, а затем if defined res
, что немного более устойчиво к опечаткам и работает даже в блоках без явного включения отложенного раскрытия.
- person Joey; 27.01.2010
Оператор IF
не поддерживает логические операторы AND
и OR
. Каскадные операторы IF
создают неявное соединение:
IF Exist File1.Dat IF Exist File2.Dat GOTO FILE12_EXIST_LABEL
Если File1.Dat
и File2.Dat
существуют, перейдите к метке FILE12_EXIST_LABEL
.
См. Также: IF /?
Законы Де Моргана позволяют нам преобразовывать дизъюнкции («ИЛИ») в логические эквиваленты, используя только союзы. («И») и отрицания («НЕ»). Это означает, что мы можем связать дизъюнкции («ИЛИ») в одну строку.
Это означает, что если имя «Якко», или «Вакко», или «Точка», то повторяется «брат или сестра Уорнера».
set warner=true
if not "%name%"=="Yakko" if not "%name%"=="Wakko" if not "%name%"=="Dot" set warner=false
if "%warner%"=="true" echo Warner brother or sister
Это еще одна версия примера «ИЛИ» paxdiablo, но условия привязаны к одной строке. (Обратите внимание, что противоположность leq
- gtr
, а противоположность geq
- lss
.)
set res=true
if %hour% gtr 6 if %hour% lss 22 set res=false
if "%res%"=="true" set state=asleep
ИЛИ - это немного сложно, но не слишком. Вот пример
set var1=%~1
set var2=%~2
::
set or_=
if "%var1%"=="Stack" set or_=true
if "%var2%"=="Overflow" set or_=true
if defined or_ echo Stack OR Overflow
В следующих примерах показано, как составить оператор И (используемый для установки переменных или включения параметров для команды).
Чтобы запустить Блокнот и закрыть окно CMD:
start notepad.exe & exit
Чтобы установить переменные x, y и z в значения, если переменная 'a' равна blah.
IF "%a%"=="blah" (set x=1) & (set y=2) & (set z=3)
Надеюсь, это поможет!
Если вам интересно написать _1 _ + _ 2 _ / _ 3_ в одном операторе, то его нет. Но вы все равно можете сгруппировать if
с операторами _5 _ / _ 6_ и _7 _ / _ 8_, чтобы достичь желаемого в одной строке без каких-либо дополнительных переменных и без дублирования блоков if-else
(одна команда echo
для разделов кода TRUE
и FALSE
):
@echo off
setlocal
set "A=1" & set "B=2" & call :IF_AND
set "A=1" & set "B=3" & call :IF_AND
set "A=2" & set "B=2" & call :IF_AND
set "A=2" & set "B=3" & call :IF_AND
echo.
set "A=1" & set "B=2" & call :IF_OR
set "A=1" & set "B=3" & call :IF_OR
set "A=2" & set "B=2" & call :IF_OR
set "A=2" & set "B=3" & call :IF_OR
exit /b 0
:IF_OR
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) || ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) || ( echo.FALSE-& type 2>nul ) ) && echo TRUE+
exit /b 0
:IF_AND
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) && ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) && echo.TRUE+ ) || echo.FALSE-
exit /b 0
Вывод:
TRUE+
FALSE-
FALSE-
FALSE-
TRUE+
TRUE+
TRUE+
FALSE-
Уловка заключается в команде type
, которая сбрасывает / устанавливает errorlevel
и таким образом обрабатывает путь к следующей команде.
if %A% EQU 1
, if %B% EQU 2
, где :IF_OR
означает if %A% EQU 1
ИЛИ if %B% EQU 2
соответственно.
- person Andry; 03.12.2020
Атул Пракаш (в то время 16 лет) дал логическую идею о том, как реализовать тест ИЛИ, отрицая условия в операторах IF и затем используя предложение ELSE в качестве места для размещения кода, который требует выполнения. Я подумал про себя, что, однако, обычно необходимы два предложения else, поскольку он предлагает использовать два оператора IF, и поэтому выполняемый код нужно писать дважды. Однако, если GOTO используется для пропуска необходимого кода, вместо того, чтобы писать предложения ELSE, код для выполнения нужно писать только один раз.
Вот проверяемый пример того, как я бы реализовал отрицательную логику Атула Пракаша для создания операции ИЛИ.
В моем примере кому-то разрешено водить танк, если у него есть лицензия на танк ИЛИ он проходит военную службу. В ответ на два запроса введите true или false, и вы сможете увидеть, позволяет ли логика управлять танком.
@ECHO OFF
@SET /p tanklicence=tanklicence:
@SET /p militaryservice=militaryservice:
IF /I NOT %tanklicence%==true IF /I NOT %militaryservice%==true GOTO done
ECHO I am driving a tank with tanklicence set to %tanklicence% and militaryservice set to %militaryservice%
:done
PAUSE
Это так же просто, как следующее:
И> если + если
if "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" *do something*
OR> if // if
set BOTH=0
if "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" set BOTH=1
if "%BOTH%"=="0" if "%VAR1%"=="VALUE" *do something*
if "%BOTH%"=="0" if "%VAR2%"=="VALUE" *do something*
Я знаю, что есть и другие ответы, но я думаю, что шахта проще, поэтому ее легче понять. Надеюсь, это вам поможет! ;)
Попробуйте операнд отрицания - «не»!
Что ж, если вы можете выполнить операцию «И» над оператором if, используя вложенные «if» (см. Предыдущие ответы), то вы можете сделать то же самое с «if not», чтобы выполнить операцию «или».
Если вы еще не совсем поняли, читайте дальше. В противном случае просто не теряйте время и вернитесь к программированию.
Так же, как вложенные «если» выполняются только тогда, когда все условия истинны, вложенные «если нет» удовлетворяются только тогда, когда все условия ложны. Это похоже на то, что вы хотите сделать с операндом «или», не так ли?
Даже когда любое из условий вложенного «if not» истинно, все утверждение остается невыполненным. Следовательно, вы можете последовательно использовать отрицательные if, помня, что тело оператора условия должно быть тем, что вы хотите делать, если все ваши вложенные условия ложны. Тело, которое вы действительно хотели передать, должно подпадать под действие else.
И если вы все еще не поняли суть дела, извините, мне 16, и это лучшее, что я могу сделать, чтобы объяснить.
Альтернативой является поиск оболочки unix, которая дает вам логические операторы и многое другое. Вы можете получить встроенную реализацию Win32 оболочки Bourne здесь, если не хотите идти по пути cygwin . Собственный bash можно найти здесь. Я совершенно уверен, что вы могли бы легко найти в Google другие хорошие альтернативы, такие как zsh или tcsh.
K
Сложна только часть ИЛИ, но с общим логическим выражением, содержащим НЕ ИЛИ И, единственное хорошее решение:
REM if A == B OR C == C then yes
(call :strequ A B || call :strequ C C) && echo yes
exit /b
:strequ
if "%1" == "%2" exit /b 0
exit /b 1
Небольшая модификация ответа Андри, уменьшающая повторяющиеся команды типа:
set "A=1" & set "B=2" & call :IF_AND
set "A=1" & set "B=3" & call :IF_AND
set "A=2" & set "B=2" & call :IF_AND
set "A=2" & set "B=3" & call :IF_AND
echo.
set "A=1" & set "B=2" & call :IF_OR
set "A=1" & set "B=3" & call :IF_OR
set "A=2" & set "B=2" & call :IF_OR
set "A=2" & set "B=3" & call :IF_OR
goto :eof
:IF_OR
(if /i not %A% EQU 1 (
if /i not %B% EQU 2 (
echo FALSE-
type 2>nul
)
)) && echo TRUE+
goto :eof
:IF_AND
(if /i %A% EQU 1 (
if /i %B% EQU 2 (
echo TRUE+
type 2>nul
)
)) && echo FALSE-
goto :eof