DOSバッチの論理演算子(「and」、「or」)


回答:


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、タイプミスに対してもう少し堅牢であり、遅延拡張を明示的に有効にせずにブロックでも機能します。
Joey

5
答えを少し改善するために... "if"ステートメントを明示的にネストする必要はありません... Dave Jarvisが以下に示すように、それらを "チェーン"することができます
JoelFan

set = trueの後にスペースを残さないように注意してください。そうしないと、正常に機能しません。変数に値「true」を格納します...
Roland Pihlakas

1
あなたが説明する 'or'条件は洗練されていて、ある範囲の数値に対してはうまく機能しますが、範囲ではなく2つの独立した値を比較している場合はどうなりますか?たとえば、このファイルが存在する場合、またはファイル名== ""の場合
bakoyaro

1
@bakoyaro、あなたが言及したものを含め、任意の条件を使用してresを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

ドモルガンの法則により、論理積( "OR")を論理積( "AND")と否定( "NOT")のみを使用して論理的に等価に変換できます。つまり、論理和( "OR")を1行につなげることができます。

これは、名前が「やっこ」、「わっこ」、「ドット」の場合、「ワーナーの兄弟または姉妹」をエコーし​​ます。

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の「OR」の例の別のバージョンですが、条件は1行にチェーンされています。(注その反対leqIS gtrとの対向geqIS 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

変数 'a'がblahと等しい場合、変数x、y、およびzに値を設定します。

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

お役に立てば幸いです。


5

ORは少しトリッキーですが、それほどトリッキーではありません。ここに例があります

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

Athul Prakash(当時16歳)は、IFステートメントの条件を否定し、ELSE句を場所として使用して、実行が必要なコードを配置することにより、ORテストを実装する方法について論理的なアイデアを提供しました。しかし、彼は2つのIFステートメントの使用を提案しているため、通常は2つのelse句が必要であり、実行されるコードを2回記述する必要があると思いました。ただし、GOTOを使用して必要なコードをスキップする場合は、ELSE句を記述する代わりに、実行用のコードを1回記述するだけで済みます。

以下は、Athul Prakashの否定論理を実装してORを作成する方法のテスト可能な例です。

私の例では、誰かが戦車免許を持っているか、兵役をしている場合誰かが戦車を運転することを許可されています。入力またはの2つのプロンプトに、あなたは、ロジックは、あなたがタンクを駆動することを可能にするかどうかを確認することができます。

@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/をOR1つのステートメントで、その後何の任意のそれのはありません。ただし、/ および/ ステートメントでグループ化ifして、追加の変数を使用せず、ブロックを複製せずに1行で実行することもできます(単一のコマンドとコードセクション)。&&||()if-elseechoTRUEFALSE

@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」を使用してifステートメントで「AND」演算を実行できる場合(前の回答を参照)、「if not」で同じことを実行して「or」演算を実行できます。

まだアイデアがわからない場合は、読み進めてください。それ以外の場合は、時間を無駄にせずにプログラミングに戻ってください。

すべての条件がtrueの場合にのみネストされた「if」が満たされるのと同じように、すべての条件がfalseの場合にのみネストされた「if not」が満たされます。これは、「または」オペランドを使用して実行する処理に似ていますね。

ネストされた「if not」の条件のいずれかが真であっても、ステートメント全体が満たされないままです。したがって、ネストされたすべての条件がfalseの場合に条件ステートメントの本文を実行する必要があることを覚えておくことで、否定の「if」を続けて使用できます。あなたが実際に与えたかった体は、elseステートメントの下にあるはずです。

それでもまだその要点がわからない場合は、申し訳ありませんが、私は16歳です。それが、私が説明できる最善の方法です。


x = 2またはx = 3 =>!!(x = 2またはx = 3)=>!(x!= 2およびx!= 3)必要な外部の「not」演算子を適用するために構造体if全体を否定することはできないと思います。@ Athul-prakash、考えて3年になりますか?
Azeroth2b 2017年

1

次のように簡単です。

AND> if + if

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*

他にも答えはあると思いますが、鉱山の方がシンプルなので理解しやすいと思います。これがお役に立てば幸いです!;)


0

別の方法は、論理演算子やその他多くの機能を提供するUNIXシェルを探すことです。cygwinルートを使いたくない場合は、ここで Bourneシェルのネイティブwin32実装を取得できます。ネイティブbashはここにあります。zshやtcshなど、他の優れた代替手段を簡単にググることができると私は確信しています。

K


4
別のシェルを使用する必要がある場合は、少なくともPowerShellを使用してください。microsoft.com
Eclipse

17
DOSよりも多くの優れたシェルがあります。DOS batファイルを使用する理由は、外部ツールを必要としないためです。単純なものを自動化する必要がある顧客がいる場合、BATファイルで十分なときに、特別なツール(cygwin、perl、powershellなど)をインストールする必要がありますか?
Mark Lakata、2011

3
ほとんどの場合、BATで十分です。UNIXシェルスクリプトの90%は、ppl書き込みが純粋なシェルではなく、多数のcoreutils、sed、awkなどの呼び出しを伴います。GNUは、Windowsを含む他のOSにUNIXの優れた機能を実装しています。したがって、このgetgnuwin32.sourceforge.net cmd.exe / bash / zshを確認してください。さらに、ほとんどのタスクでこれで十分です。BAT / UNIXシェルの経験がある場合は、いわゆるPowerShellを学ぶ必要はありません
MeaCulpa

0

OR部分のみがトリッキーですが、NOT OR ANDを含む一般的なブール式では、唯一の優れたソリューションは次のとおりです。

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

Andryの答えを少し変更して、重複するtypeコマンドを減らします。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.