Czy istnieje sposób zapisania instrukcji warunkowej IF OR IF w pliku wsadowym systemu Windows?
Na przykład:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
windows
batch-file
if-statement
cmd
conditional
Mechaflash
źródło
źródło
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
. Użyłem do zdefiniowaniaSET AND=IF
, a następnie napisać:IF cond1 %AND% cond2 ECHO BOTH ARE TRUE
.Odpowiedzi:
Rozwiązanie zmbq jest dobre, ale nie może być używane we wszystkich sytuacjach, takich jak wewnątrz bloku kodu, takiego jak pętla FOR DO (...).
Alternatywą jest użycie zmiennej wskaźnikowej. Zainicjuj go, aby był niezdefiniowany, a następnie zdefiniuj go tylko wtedy, gdy jeden z warunków LUB jest prawdziwy. Następnie użyj funkcji IF DEFINED jako ostatecznego testu - nie ma potrzeby używania opóźnionego rozszerzania.
Możesz dodać logikę ELSE IF, której używa arasmussen na tej podstawie, że może działać trochę szybciej, jeśli pierwszy warunek jest prawdziwy, ale nigdy się nie przejmuję.
Dodatek - jest to zduplikowane pytanie z prawie identycznymi odpowiedziami na temat używania OR w instrukcji IF WinXP Batch Script
Dodatek końcowy - prawie zapomniałem o mojej ulubionej technice sprawdzania, czy zmienna jest jedną z listy wartości niewrażliwych na wielkość liter. Zainicjuj zmienną testową zawierającą rozdzielaną listę dopuszczalnych wartości, a następnie użyj funkcji wyszukiwania i zamieniania, aby sprawdzić, czy zmienna znajduje się na liście. Jest to bardzo szybkie i wykorzystuje minimalny kod dla dowolnie długiej listy. Wymaga opóźnionej ekspansji (lub sztuczki CALL %% VAR %%). Test jest również niewrażliwy na wielkość liter.
Powyższe może się nie powieść, jeśli VAR zawiera
=
, więc test nie jest niezawodny .Jeśli wykonujesz test w bloku, w którym potrzebne jest opóźnione rozwinięcie, aby uzyskać dostęp do bieżącej wartości VAR, to
W zależności od oczekiwanych wartości w VAR mogą być potrzebne opcje FOR, takie jak „delims =”
Powyższą strategię można uczynić niezawodną nawet
=
w przypadku VAR, dodając nieco więcej kodu.Ale teraz straciliśmy możliwość dostarczania klauzuli ELSE, chyba że dodamy zmienną wskaźnikową. Kod zaczął wyglądać trochę "brzydko", ale myślę, że jest to najlepsza niezawodna metoda testowania, jeśli VAR jest jedną z dowolnej liczby opcji bez rozróżniania wielkości liter.
Wreszcie jest prostsza wersja, która moim zdaniem jest nieco wolniejsza, ponieważ musi wykonywać jedną IF dla każdej wartości. Aacini podał to rozwiązanie w komentarzu do zaakceptowanej odpowiedzi w powyższym linku
Lista wartości nie może zawierać znaku * ani? znaków oraz wartości i
%VAR%
nie powinny zawierać cudzysłowów. Cytaty prowadzić do problemów, jeśli%VAR%
zawiera spacje lub znaki specjalne, takie jak^
,&
itd jednego innego ograniczenia ze jest to nie przewiduje opcję dla ELSE klauzuli chyba dodać zmienną wskaźnikową tego rozwiązania. Zaletą jest to, że może być uwzględniana wielkość liter lub niewrażliwa, w zależności od obecności lub braku/I
opcji IF .źródło
Nie sądzę. Po prostu użyj dwóch IF i GOTO tej samej etykiety:
źródło
ECHO Didn't find it
nawet, gdyby go znalazł.Dzięki za ten post, bardzo mi pomógł.
Nie wiem, czy to może pomóc, ale miałem problem i dzięki tobie znalazłem inny sposób rozwiązania go w oparciu o tę logiczną równoważność:
„A lub B” to to samo, co „nie (nie A i nie B)”
A zatem:
Staje się:
źródło
Aby użyć warunku „lub”, można użyć prostego „FOR” w pojedynczym wierszu:
Dotyczy twojego przypadku:
źródło
Nawet jeśli to pytanie jest trochę starsze:
Jeśli chcesz używać
if cond1 or cond 2
- nie powinieneś używać skomplikowanych pętli lub podobnych rzeczy.Proste dostarczanie obu
ifs
po sobie w połączeniu zgoto
- to niejawne lub.Bez działania goto, ale „inplace”, możesz wykonać akcję 3 razy, jeśli WSZYSTKIE warunki są zgodne.
źródło
Nie ma
IF <arg> OR
aniELIF
czyELSE IF
w trybie wsadowym, jednak ...Spróbuj zagnieździć inne IF wewnątrz ELSE poprzedniego IF.
źródło
Możliwe jest użycie funkcji, która ocenia logikę OR i zwraca pojedynczą wartość.
źródło
&& ... || ...
składni bezpośrednio zamiast dodatkowejIF ... ELSE ...
instrukcji.Cel można osiągnąć poprzez pośrednie wykorzystanie FI.
Poniżej znajduje się przykład złożonego wyrażenia, które można zapisać dość zwięźle i logicznie w partii CMD, bez niespójnych etykiet i GOTO.
Bloki kodu w nawiasach () są traktowane przez CMD jako (żałosny) rodzaj podpowłoki. Cokolwiek kod wyjścia wychodzi z bloku, zostanie użyty do określenia wartości prawda / fałsz, którą blok odtwarza w większym wyrażeniu logicznym. Z tych bloków kodu można zbudować dowolnie duże wyrażenia logiczne.
Prosty przykład
Każdy blok jest przetwarzany na prawdę (tj. ERRORLEVEL = 0 po wykonaniu ostatniej instrukcji w bloku) / fałsz, dopóki wartość całego wyrażenia nie zostanie określona lub sterowanie wyskoczy (np. Przez GOTO):
Złożony przykład
To rozwiązuje problem podniesiony na początku. W każdym bloku jest możliwych wiele instrukcji, ale w || || || wyrażenie lepiej jest być zwięzłe, aby było jak najbardziej czytelne. ^ jest znakiem ucieczki w paczkach CMD i po umieszczeniu na końcu wiersza będzie oznaczał wyjście z EOL i poinstruowanie CMD, aby kontynuował czytanie bieżącej serii instrukcji w następnym wierszu.
źródło
Służy do sprawdzania, czy wiele zmiennych ma taką samą wartość. Tutaj jest dla każdej zmiennej.
Po prostu pomyślałem o tym z góry, jeśli moja głowa. Mógłbym to bardziej zagęścić.
źródło
Zdaję sobie sprawę, że to pytanie jest stare, ale chciałem opublikować alternatywne rozwiązanie na wypadek, gdyby ktoś inny (taki jak ja) znalazł ten wątek, mając to samo pytanie. Byłem w stanie obejść brak operatora OR, wywołując echo zmiennej i używając findstr do walidacji.
źródło
Chociaż odpowiedź dbenham jest całkiem dobra, poleganie na niej
IF DEFINED
może przysporzyć Ci wielu kłopotów, jeśli sprawdzana zmienna nie jest zmienną środowiskową . Zmienne skryptowe nie są traktowane w ten specjalny sposób.Chociaż może się to wydawać absurdalnym, nieudokumentowanym BS, wykonanie prostego zapytania w powłoce za
IF
pomocąIF /?
ujawnia, że:Jeśli chodzi o odpowiedź na to pytanie, czy istnieje powód, aby nie używać prostej flagi po serii ocen? Wydaje
OR
mi się, że jest to najbardziej elastyczne sprawdzenie, zarówno pod względem logiki, jak i czytelności. Na przykład:Oczywiście mogą to być dowolne oceny warunkowe, ale podam tylko kilka przykładów.
Jeśli chcesz mieć to wszystko w jednej linii, pod względem pisma, możesz po prostu połączyć je razem za pomocą
&&
:źródło
Nigdy nie przyszedłem do pracy.
Używam jeśli nie istnieje g: xyz / what goto h: Else xcopy c: current / files g: bu / current Istnieją modyfikatory / a itp. Nie wiem, które z nich. Laptop w sklepie. I komputer w biurze. Mnie tam nie ma.
Pliki wsadowe nigdy nie działały w systemie Windows XP
źródło
O wiele szybsza alternatywa, której zwykle używam, jest następująca, ponieważ mogę "lub" dowolna liczba warunków, które mogą zmieścić się w zmiennej przestrzeni
źródło
Zdając sobie sprawę, że jest to trochę stare pytanie, odpowiedzi pomogły mi wymyślić rozwiązanie testowania argumentów wiersza poleceń w pliku wsadowym; dlatego też chciałem zamieścić moje rozwiązanie na wypadek, gdyby ktoś inny szukał podobnego rozwiązania.
Pierwszą rzeczą, na którą powinienem zwrócić uwagę, jest to, że miałem problem z uzyskaniem działania instrukcji IF ... ELSE wewnątrz klauzuli FOR ... DO. Okazuje się (dzięki dbenhamowi za nieumyślne wskazanie tego w swoich przykładach), że instrukcja ELSE nie może znajdować się w oddzielnym wierszu od zamykających par.
Więc zamiast tego:
Które preferuję ze względu na czytelność i estetykę, musisz to zrobić:
Teraz instrukcja ELSE nie zwraca jako nierozpoznane polecenie.
Wreszcie, oto co próbowałem zrobić - chciałem móc przekazać kilka argumentów do pliku wsadowego w dowolnej kolejności, ignorując wielkość liter i zgłaszając / niepowodzenie w przekazywaniu niezdefiniowanych argumentów. Oto moje rozwiązanie ...
Uwaga, to zgłosi tylko pierwszy nieudany argument. Jeśli więc użytkownik poda więcej niż jeden niedopuszczalny argument, zostanie mu poinformowany tylko o pierwszym, dopóki nie zostanie poprawiony, potem o drugim itd.
źródło