これらのコマンドをこのように使用すると、期待どおりに動作します。
もしfoo
だった以前に何らかの設定をした場合、foobar_menu
foo
以前にない同じものとして設定すると、another_menu
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
rem Check if foo was NOT previously set as bar1 or bar2...
if not "%foo%"=="bar1" goto :another_menu
if not "%foo%"=="bar2" goto :another_menu
これが私を混乱させる理由です。以下に示すようにこれらを入れ替えると、正しく動作せず、間違ったラベルに移動しますが、なぜでしょうか?
rem Check if foo was NOT previously set as bar1 or bar2...
if not "%foo%"=="bar1" goto :another_menu
if not "%foo%"=="bar2" goto :another_menu
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
なぜこれら 2 つは同じことを行わないのでしょうか?
これは、goto 部分を括弧で囲んでいないためでしょうか?
私はこれを(最初の方法で)動作させていますが、これはメニューの順序と同じではありません。私は、すべてを上記の 2 番目の(動作しない)例のレイアウトどおりに実行させたいだけです。
乾杯。
編集:
choose_audio_sample_rate
これらは実際のコマンドです。このように記述すると、ネストされていても、変数の下に opus または libopus が設定されていても、ラベルに移動します。
if not "%audio_codec%"=="libopus" if not "%audio_codec%"=="opus" goto :choose_audio_sample_rate
if "%audio_codec%"=="libopus" if "%audio_codec%"=="opus" goto :choose_audio_sample_rate_opus
実際、スワップされたバージョンも機能せず、choose_audio_sample_rate
変数の下に opus または libopus が設定されていても機能します。
if "%audio_codec%"=="libopus" if "%audio_codec%"=="opus" goto :choose_audio_sample_rate_opus
if not "%audio_codec%"=="libopus" if not "%audio_codec%"=="opus" goto :choose_audio_sample_rate
私はここで狂人になりつつあります(笑)、OK、これだけを使えばうまくいきます(そして非 Opus メニューに直接進みます):
if "%audio_codec%"=="libopus" (goto :choose_audio_sample_rate_opus)
if "%audio_codec%"=="opus" (goto :choose_audio_sample_rate_opus)
libopus の場合は、正しいラベルに移動します。libopus でない場合は、次の行が処理され、opus の場合は、正しいラベルに移動します。
それを過ぎると、libopus も opus もなくなり、一般メニューに進みます。
答え1
バッチ ファイルは上から下に実行されます。
2 番目の例では、 またはfoo2
がfoo1
設定されていても、常に に移動します:another_menu
。バッチ ファイルがこれら 2 つのステートメントを通過できるのは、 とfoo1
の両方foo2
が設定されている場合のみです。
本質的には、論理 OR 状況を作り出していることになります。
foo1またはfoo2が設定されていない場合はanother_menuに進みます
それ以外
foo1またはfoo2が設定されている場合はfoobar_menuに移動します
それ以外
何もしない
最初の例では、
foo1またはfoo2が設定されている場合はfoobar_menuに移動します
それ以外
foo1またはfoo2が設定されていない場合はanother_menuに進みます
それ以外
何もしない
必要なのは、具体的には論理 AND です。バッチ ファイルの IF ステートメントは、AND も OR もサポートしていません。そのため、次のようにネストまたは連結します。
if not "%foo1%"=="bar1" if not "%foo2%"=="bar2" goto :another_menu
これは、foo1が設定されていない場合、foo2が設定されていない場合は:another_menuに移動します。
または、もっと簡単に言うと、foo1とfoo2が設定されていない場合は別のメニューに移動します
答え2
findstrを使用するとロジックを少し簡素化できます
Echo("%foo%"|Findstr /C:"bar1" /C:"bar2" > nul && Goto :FooBarMenu || Goto :AnotherMenu
ロジック: Findstr は文字列%foo%
を bar1 および bar2 と比較します。一致した場合、コマンドは正常に完了し、条件演算子は&&
次のコマンドを実行します。一致しない場合は、||
前のコマンドが正常に実行されなかったため、条件演算子がトリガーされ、次のコマンドが実行されます。
例:
@Echo off
Set "foo=notbar"
:loop
Echo("%foo%"|Findstr /C:"bar1" /C:"bar2" > nul ^
&& Call :fooBarMenu foobarMenu || Call :AnotherMenu Anothermenu
If not defined foo Exit /B 0
Goto :loop
:foobarmenu
Echo(@ %~1 foo = %foo%
Set "foo="
Exit /B 0
:Anothermenu
Echo(@ %~1 foo = %foo%
Set "foo=bar2"
Exit /B 0
答え3
bar1
とはすでにチェック済みです。したがって、 または でないかどうかbar2
を再度チェックする必要はありません(コード フローがこの時点に到達したときには、すでに別の場所に分岐しているため、確実に ではありません)。bar1
bar2
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
rem no need to check if foo was NOT previously set as bar1 or bar2
rem if FOO is anything other than the previously checked values,
rem your code will continue here anyway.
echo FOO isn't bar1 or bar2.
rem Don't forget to end this branch of your code or it will just continue to run:
goto :eof
:foobar_menu
echo reached foobar.
大文字小文字を無視するに/i
は、スイッチの使用を検討してください (is false、is true)if
if "foo"=="FOO"
if /i "foo"=="FOO"