Логические операторы («и», «или») в пакете DOS


Ответы:


289

Вы можете сделать andс вложенными условиями:

if %age% geq 2 (
    if %age% leq 12 (
        set class=child
    )
)

или:

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
)

14
Вы также можете просто использовать set res=или set res=1и то, if defined resчто немного более устойчиво к опечаткам и работает даже в блоках без явного включения отложенного расширения.
Джои

5
Просто чтобы немного улучшить свой ответ ... вам не нужно явно
вкладывать выражения

Остерегайтесь не оставлять пробелов после set = true, иначе вещь просто изящно не работает. Это будет хранить значение «true» в переменной ...
Роланд Пихлакас

1
Условие «или», которое вы описываете, является гладким и прекрасно работает для диапазона чисел, но что, если я сравниваю 2 независимых значения, а не диапазон? Например, если этот файл существует или имя файла == ""
bakoyaro

1
@bakoyaro, вы можете использовать любое условие для установки значения true, включая те, которые вы упомянули.
paxdiablo

69

Оператор IFне поддерживает логические операторы ( ANDи OR), каскадные IFоператоры создают неявное соединение.

IF Exist File1.Dat IF Exist File2.Dat GOTO FILE12_EXIST_LABEL

Если File1.Dat и File1.Dat существует, то прыгнуть ярлык FILE12_EXIST_LABEL.

Смотрите также: IF /?


53

Законы де Моргана позволяют нам преобразовывать дизъюнкции («ИЛИ») в логические эквиваленты, используя только конъюнкции («И») и отрицания («НЕ»). Это означает, что мы можем связать дизъюнкции («ИЛИ») в одну строку.

Это означает, что если зовут «Якко» или «Вакко» или «Точка», то эхо «Уорнер брат или сестра».

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

Это еще одна версия примера «ИЛИ» Паккдиабло, но условия связаны одной строкой. (Обратите внимание, что противоположность leqесть gtr, а противоположность geqесть lss.)

set res=true
if %hour% gtr 6 if %hour% lss 22 set res=false
if "%res%"=="true" set state=asleep

6

В следующих примерах показано, как сделать оператор AND (используется для установки переменных или включения параметров для команды).

Чтобы запустить Блокнот и закрыть окно CMD:

start notepad.exe & exit

Установить переменные x, y и z в значения, если переменная 'a' равна бла.

IF "%a%"=="blah" (set x=1) & (set y=2) & (set z=3)

Надеюсь, это поможет!


5

ИЛИ немного сложнее, но не слишком. Вот пример

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

2

Атул Пракаш (в то время ему было 16 лет) дал логическую идею о том, как реализовать тест OR, отменив условия в операторах IF, а затем используя предложение 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

2

Если вам интересно написать if+ AND/ ORв одном утверждении, то его нет. Но, вы можете по- прежнему группа ifс &&/ ||и (/ )заявления добиться того, что вы хотите в одной строке без каких - либо дополнительных переменных и без 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и обрабатывает путь к следующей команде.


1

Попробуйте операнд отрицания - «нет»!

Что ж, если вы можете выполнить операцию «И» над оператором if с использованием вложенных «если» (см. Предыдущие ответы), то вы можете сделать то же самое с «если нет» для выполнения операции «или».

Если вы еще не поняли идею, читайте дальше. В противном случае, просто не тратьте свое время и вернитесь к программированию.

Так же, как вложенные «если» удовлетворяются только тогда, когда все условия выполняются, вложенные «если нет» выполняются только тогда, когда все условия являются ложными. Это похоже на то, что вы хотите сделать с операндом 'или', не так ли?

Даже если любое из условий во вложенном «если нет» верно, все утверждение остается неудовлетворенным. Следовательно, вы можете использовать отрицательное «если последовательно», помня, что тело оператора условия должно быть тем, что вы хотите сделать, если все ваши вложенные условия ложны. Тело, которое вы на самом деле хотели дать, должно соответствовать заявлению else.

И если вы все еще не поняли суть дела, извините, мне 16 лет, и это лучшее, что я могу сделать, чтобы объяснить.


х = 2 или х = 3 =>! ! (x = 2 или x = 3) =>! (x! = 2 и x! = 3) Я не думаю, что вы можете отрицать целую структуру if для применения необходимого внешнего оператора «not». Прошло 3 года, @ Athul-prakash, мысли?
Azeroth2b

1

Это так же просто, как следующее:

И> если + если

if "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" *do something*

ИЛИ> если // если

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*

Я знаю, что есть и другие ответы, но я думаю, что шахта более проста, поэтому ее легче понять. Надеюсь, это поможет вам! ;)


0

Альтернативой является поиск оболочки Unix, которая дает вам логические операторы и многое другое. Вы можете получить родную реализация win32 из Bourne оболочки здесь , если вы не хотите идти Cygwin маршрута. Родной Bash можно найти здесь . Я совершенно уверен, что вы могли бы легко найти другие хорошие альтернативы, такие как zsh или tcsh.

К


4
Если вы собираетесь использовать другую оболочку, по крайней мере, используйте PowerShell: microsoft.com/powershell
Eclipse

17
Есть много лучших оболочек, чем DOS. Причина, по которой я бы использовал файл bat для DOS, заключается в том, что он не требует никаких внешних инструментов. Если у вас есть клиент, которому нужно автоматизировать что-то простое, действительно ли вы хотите, чтобы он устанавливал специальные инструменты (cygwin, perl, powershell и т. Д.), Когда файла BAT будет достаточно?
Марк Лаката

3
НИМ достаточно времени. 90% сценариев оболочки Unix, написанных на языке ppl, - это не чистая оболочка, а множество вызовов coreutils, sed, awk и т. Д. GNU реализовал вкусности UNIX в других ОС, включая Windows. Так что взгляните на этот getgnuwin32.sourceforge.net cmd.exe / bash / zsh, плюс этого должно быть достаточно для большинства задач. Нет смысла изучать так называемую PowerShell, если у вас есть опыт работы с BAT / UNIX Shell
MeaCulpa

0

Только часть OR хитрая, но с общим логическим выражением, содержащим NOT OR, и единственное хорошее решение - это:

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

-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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.