Логические операторы (and, or) в пакете DOS

Как бы вы реализовали логические операторы в пакетных файлах DOS?


person JoelFan    schedule 26.01.2010    source источник
comment
Для вашего удовольствия представляю: pi.bat :) thedailywtf.com/Articles/   -  person Scott Anderson    schedule 27.01.2010


Ответы (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
)
person paxdiablo    schedule 26.01.2010
comment
Вы также можете просто использовать set res= или set res=1, а затем if defined res, что немного более устойчиво к опечаткам и работает даже в блоках без явного включения отложенного раскрытия. - person Joey; 27.01.2010
comment
Просто чтобы немного улучшить свой ответ ... вам не нужно явно вкладывать операторы if ... вы можете просто связать их, как демонстрирует Дэйв Джарвис ниже - person JoelFan; 28.01.2010
comment
Befare не оставлять пробелов после set = true, иначе вещь просто изящно не сработает. Он сохранит значение true в переменной ... - person Roland Pihlakas; 30.08.2015
comment
Условие «или», которое вы описываете, гладкое и отлично работает для диапазона чисел, но что, если я сравниваю 2 независимых значения, а не диапазон? Например, если этот файл существует или filename == - person bakoyaro; 15.12.2017
comment
@bakoyaro, вы можете использовать любое условие, чтобы установить для res значение true, включая те, которые вы упомянули. - person paxdiablo; 15.12.2017

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

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

Если File1.Dat и File2.Dat существуют, перейдите к метке FILE12_EXIST_LABEL.

См. Также: IF /?

person Dave Jarvis    schedule 26.01.2010

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

Это означает, что если имя «Якко», или «Вакко», или «Точка», то повторяется «брат или сестра Уорнера».

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
person anomal    schedule 16.05.2012

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

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
person Timo Salmi    schedule 23.07.2012
comment
Не работает. Если я дам ему Stack, он отзовется. Если я дам ему Overflow, этого не произойдет - должно. - person Unknow0059; 03.12.2020

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

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

start notepad.exe & exit

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

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

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

person GinDiamond    schedule 30.11.2011

Если вам интересно написать _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 и таким образом обрабатывает путь к следующей команде.

person Andry    schedule 22.07.2017
comment
Какое фактическое состояние здесь проверяется? Сложно сказать. - person Unknow0059; 03.12.2020
comment
@ Unknow0059 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
person Ivan    schedule 17.08.2015

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

И> если + если

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*

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

person Renk Software    schedule 22.12.2015

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

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

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

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

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

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

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

Альтернативой является поиск оболочки unix, которая дает вам логические операторы и многое другое. Вы можете получить встроенную реализацию Win32 оболочки Bourne здесь, если не хотите идти по пути cygwin . Собственный bash можно найти здесь. Я совершенно уверен, что вы могли бы легко найти в Google другие хорошие альтернативы, такие как zsh или tcsh.

K

person Kevin Shea    schedule 26.01.2010
comment
Если вы собираетесь использовать другую оболочку, по крайней мере, используйте PowerShell: microsoft.com/powershell < / а> - person Eclipse; 15.03.2010
comment
Есть много оболочек лучше, чем DOS. Причина, по которой я бы использовал bat-файл DOS, заключается в том, что он не требует каких-либо внешних инструментов. Если у вас есть заказчик, которому нужно автоматизировать что-то простое, действительно ли вы хотите, чтобы он установил специальные инструменты (cygwin, perl, powershell и т. Д.), Когда будет достаточно BAT-файла? - person Mark Lakata; 21.07.2011

Сложна только часть ИЛИ, но с общим логическим выражением, содержащим НЕ ИЛИ И, единственное хорошее решение:

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
person Henrik4    schedule 22.04.2020

Небольшая модификация ответа Андри, уменьшающая повторяющиеся команды типа:

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
person TedK    schedule 21.09.2017