Jak używać struktury if - else w pliku wsadowym?

136

Mam pytanie o strukturę if - else w pliku wsadowym. Każde polecenie działa osobno, ale nie mogłem bezpiecznie używać bloków „if - else”, więc te części mojego programu nie działają. Jak mogę sprawić, by te części działały? Dziękuję Ci.

IF %F%==1 IF %C%==1 (
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    )
ELSE IF %F%==1 IF %C%==0 (
    ::moving the file c to d
    move "%sourceFile%" "%destinationFile%"
    )

ELSE IF %F%==0 IF %C%==1 (
    ::copying a directory c from d, /s:  boş olanlar hariç, /e:boş olanlar dahil
    xcopy "%sourceCopyDirectory%" "%destinationCopyDirectory%" /s/e
    )
ELSE IF %F%==0 IF %C%==0 (
    ::moving a directory
    xcopy /E "%sourceMoveDirectory%" "%destinationMoveDirectory%"
    rd /s /q "%sourceMoveDirectory%"
    )
tytułowy
źródło
Czy moje pytanie jest czytelne? Czytałem to wiersz po wierszu, ale wydaje mi się, że jest to obok siebie.
tytułowy
4
Cześć, witamy w Stack Overflow! Aby utworzyć blok kodu, możesz zaznaczyć odpowiedni tekst i kliknąć {}przycisk; pomaga uczynić posty bardziej czytelnymi i pozwala uniknąć pewnych problemów ze znacznikami. Odpowiadając na twoje pytanie, teraz! Podczas pisania pytania poniżej znajduje się podgląd, dzięki czemu możesz zobaczyć, jak będzie wyglądać po opublikowaniu.
Ben
1
Więc dziękuję za wyjaśnienie. Mam zamiar użyć tej metody.
tytułowy

Odpowiedzi:

110

Twoja składnia jest nieprawidłowa. Nie możesz użyć ELSE IF. Wygląda na to, że i tak go nie potrzebujesz. Po prostu użyj wielu IFinstrukcji:

IF %F%==1 IF %C%==1 (
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    )

IF %F%==1 IF %C%==0 (
    ::moving the file c to d
    move "%sourceFile%" "%destinationFile%"
    )

IF %F%==0 IF %C%==1 (
    ::copying a directory c from d, /s:  boş olanlar hariç, /e:boş olanlar dahil
    xcopy "%sourceCopyDirectory%" "%destinationCopyDirectory%" /s/e
    )

IF %F%==0 IF %C%==0 (
    ::moving a directory
    xcopy /E "%sourceMoveDirectory%" "%destinationMoveDirectory%"
    rd /s /q "%sourceMoveDirectory%"
    )

Świetne odniesienie do pliku wsadowego: http://ss64.com/nt/if.html

James Hill
źródło
2
Proszę poprawić mnie, jeśli się mylę, ale nie sądzę, aby można było użyć &&w wielu ifwarunkach, zobacz moją alternatywną składnię?
Bali C
jeśli moje warunki if są takie: „IF% F% == 0” działa bezpiecznie, ale po dodaniu && nie działa. Jak mogę użyć dwóch warunków w warunku if?
tytułowy
1
@aprogrammer, spójrz na mój przykład. Jeśli masz wiele warunków, użyjIF condition1 IF condition 2
James Hill
Wypróbowałem twoją odpowiedź, ale nie mogłem jej uruchomić, ale spróbowałem ponownie i zmodyfikowałem kod do mojego kodu. Ostatnia sytuacja jakiejś części mojego kodu jest taka: JEŻELI% F% == 1 JEŻELI% C% == 1 (:: kopiowanie pliku c do d copy "% sourceFile%" "% destinationFile%") ELSE (JEŚLI % F% == 1 JEŻELI% C% == 0 (:: przenoszenie pliku c do d move "% sourceFile%" "% destinationFile%")) ELSE (JEŚLI% F% == 0 JEŻELI% C% == 1 (:: kopiowanie katalogu c z d, / s: boş olanlar hariç, / e: boş olanlar dahil xcopy "% sourceCopyDirectory%" "% destinationCopyDirectory%" / s / e))
eponymous
4
Co masz na myśli mówiąc, że nie możesz użyć ELSE IF? Działa dobrze pod Win7. Zobacz przykład: paste2.org/G8tMae92
bryc
56

Myślę, że w pytaniu i niektórych odpowiedziach jest trochę zamieszania co do znaczenia tego pseudokodu w DOS: JEŚLI A IF BX INNY Y. Nie oznacza to JEŻELI (A i B) WTEDY X INNY Y, ale w Fakt oznacza JEŻELI A (JEŻELI B TO X INNY Y). Jeśli test A się nie powiedzie, to całe wewnętrzne if-else zostanie zignorowane.

Jak wspomniano w jednej z odpowiedzi, w tym przypadku tylko jeden z testów może zakończyć się sukcesem, więc „else” nie jest potrzebne, ale oczywiście działa to tylko w tym przykładzie, nie jest to ogólne rozwiązanie do robienia if-else.

Można to obejść na wiele sposobów. Oto kilka pomysłów, wszystkie są dość brzydkie, ale hej, to jest (a przynajmniej był) DOS!

@echo off

set one=1
set two=2

REM Example 1

IF %one%_%two%==1_1 (
   echo Example 1 fails
) ELSE IF %one%_%two%==1_2 (
   echo Example 1 works correctly
) ELSE (
    echo Example 1 fails
)

REM Example 2

set test1result=0
set test2result=0

if %one%==1 if %two%==1 set test1result=1
if %one%==1 if %two%==2 set test2result=1

IF %test1result%==1 (
   echo Example 2 fails
) ELSE IF %test2result%==1 (
   echo Example 2 works correctly
) ELSE (
    echo Example 2 fails
)

REM Example 3

if %one%==1 if %two%==1 (
   echo Example 3 fails
   goto :endoftests
)
if %one%==1 if %two%==2 (
   echo Example 3 works correctly
   goto :endoftests
)
echo Example 3 fails
)
:endoftests
gtpunch
źródło
Myślę, że pierwsze dwa setnie potrzebują znaków procentu; powinno byćset one=1
Geoff
13

AFAIK, nie możesz zrobić if elsewsadowego, tak jak w innych językach, musi być zagnieżdżonyif .

Używając zagnieżdżonych plików if, twoja partia będzie wyglądać

IF %F%==1 IF %C%==1(
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    ) ELSE (
        IF %F%==1 IF %C%==0(
        ::moving the file c to d
        move "%sourceFile%" "%destinationFile%"
        ) ELSE (
            IF %F%==0 IF %C%==1(
            ::copying a directory c from d, /s:  boş olanlar hariç, /e:boş olanlar dahil
            xcopy "%sourceCopyDirectory%" "%destinationCopyDirectory%" /s/e
            ) ELSE (
                IF %F%==0 IF %C%==0(
                ::moving a directory
                xcopy /E "%sourceMoveDirectory%" "%destinationMoveDirectory%"
                rd /s /q "%sourceMoveDirectory%"
                )
            )
        )
    )

lub jak zasugerował James, połącz swoje łańcuchy if, jednak myślę, że właściwa składnia jest taka

IF %F%==1 IF %C%==1(
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    )
Bali C.
źródło
1
if else, zwłaszcza w językach typu C jest po prostu zagnieżdżony if. Nie musisz też zagnieżdżać ich blokami w plikach wsadowych.
Joey
@Joey Nie całkiem śledzę. Wiem, że else ifkombinacja jest po prostu zagnieżdżona, ifale nie sądziłem, że można użyć tych słów kluczowych razem w grupie, tak jak w językach C.
Bali C
Hmm, nadal nie mogę zmusić tego do pracy, ale wierzę na słowo, wiesz o czym mówisz, zostawię tę odpowiedź jako długą wersję :)
Bali C
Dziękuję za odpowiedzi, ale żadna z nich nie pojawiła się w moim kodzie.
tytułowy
inny przykład: if 1 == 1 (echo 1) else (if 1 == 1 (echo 2) else (echo 3))
JohnP2
1

Uważam, że możesz użyć czegoś takiego jak

if ___ (

do this

) else if ___ (

do this

)
user4090570
źródło
27
Czy stwierdzenie w drugim warunku nie powinno brzmieć „zrób to”?
bvj
7
@bvj Nie, nie, wszystko źle zrozumiałeś. Powinno być do fooi do bar.
yyny
Kiedy piszesz IF (test) (command) ELSE IF (test) (command), sugerujesz IF (test) (command) ELSE (IF (test) (command)). Może to czasami działać, ale jeśli uważasz, że jest to rzeczywista struktura programistyczna akceptowalna w DOS, będzie to PITA do rozwiązywania problemów, gdy się nie powiedzie.
Tim
1

Trochę późno i być może nadal dobre dla złożonych warunków if, ponieważ chciałbym dodać parametr „done”, aby zachować strukturę if-then-else:

set done=0
if %F%==1 if %C%==0 (set done=1 & echo found F=1 and C=0: %F% + %C%)
if %F%==2 if %C%==0 (set done=1 & echo found F=2 and C=0: %F% + %C%)
if %F%==3 if %C%==0 (set done=1 & echo found F=3 and C=0: %F% + %C%)
if %done%==0 (echo do something)
Stefane
źródło
0

IF...ELSE IF konstrukcje działają bardzo dobrze w plikach wsadowych, zwłaszcza gdy używasz tylko jednego wyrażenia warunkowego w każdym wierszu IF:

IF %F%==1 (
    ::copying the file c to d
    copy "%sourceFile%1" "%destinationFile1%"
) ELSE IF %F%==0 (
    ::moving the file e to f
    move "%sourceFile2%" "%destinationFile2%" )

W naszym przykładzie używasz IF...AND...IFkonstrukcji typu, w której 2 warunki muszą być spełnione jednocześnie. W tym przypadku możesz nadal używać IF...ELSE IFkonstrukcji, ale z dodatkowymi nawiasami, aby uniknąć niepewności co do następnego warunku ELSE:

IF %F%==1 (IF %C%==1 (
    ::copying the file c to d
    copy "%sourceFile1%" "%destinationFile1%" )
) ELSE IF %F%==1 (IF %C%==0 (
    ::moving the file e to f
    move "%sourceFile2%" "%destinationFile2%"))

Powyższa konstrukcja jest równoważna z:

IF %F%==1 (
    IF %C%==1 (
    ::copying the file c to d
    copy "%sourceFile1%" "%destinationFile1%"
    ) ELSE IF %C%==0 (
    ::moving the file e to f
    move "%sourceFile2%" "%destinationFile2%"))

Sekwencja przetwarzania poleceń wsadowych zależy od kolejności analizowania programu CMD.exe . Po prostu upewnij się, że twoja konstrukcja zachowuje logiczną kolejność iz reguły będzie działać. Jeśli twój skrypt wsadowy jest przetwarzany przez Cmd.exe bez błędów, oznacza to, że jest to poprawna (tj. Obsługiwana przez wersję systemu operacyjnego Cmd.exe) konstrukcja, nawet jeśli ktoś powiedział inaczej.

sambul35
źródło
0

Oto mój kod Przykład dla if..else..if
które wykonują następujące czynności

Pytaj użytkownika o nazwę procesu

Jeśli nazwa procesu jest nieprawidłowa,
to jest zapisywana do użytkownika

Error : The Processor above doesn't seem to be exist 

jeśli nazwa procesu to services
Następnie jest zapisywana do użytkownika

Error : You can't kill the Processor above 

jeśli nazwa procesu jest prawidłowa, a nie usługi
to zapisuje się użytkownikowi

proces został zabity przeztaskill

więc nazwałem go Process killer.bat
Oto mój kod:

@echo off

:Start
Rem preparing the batch  
cls
Title Processor Killer
Color 0B
Echo Type Processor name to kill It (Without ".exe")
set /p ProcessorTokill=%=%  

:tasklist
tasklist|find /i "%ProcessorTokill%.exe">nul & if errorlevel 1 (
REM check if the process name is invalid 
Cls 
Title %ProcessorTokill% Not Found
Color 0A
echo %ProcessorTokill%
echo Error : The Processor above doesn't seem to be exist    

) else if %ProcessorTokill%==services (
REM check if the process name is services and doesn't kill it
Cls 
Color 0c
Title Permission denied 
echo "%ProcessorTokill%.exe"
echo Error : You can't kill the Processor above 

) else (
REM if the process name is valid and not services
Cls 
Title %ProcessorTokill% Found
Color 0e
echo %ProcessorTokill% Found
ping localhost -n 2 -w 1000>nul
echo Killing %ProcessorTokill% ...
taskkill /f /im %ProcessorTokill%.exe /t>nul
echo %ProcessorTokill% Killed...
)

pause>nul



REM If else if Template
REM if thing1 (
REM Command here 2 ! 
REM ) else if thing2 (
REM command here 2 !
REM ) else (
REM command here 3 !
REM )
Oimar Daif
źródło
0

oto jak sobie poradziłem, jeśli inaczej, jeśli sytuacja

if %env%==dev ( 
    echo "dev env selected selected"
) else (
    if %env%==prod (
        echo "prod env selected"
    )
)

Zauważ, że nie jest to to samo, co blok if-elseif, jak inne języki programowania, takie jak C ++ lub Java, ale zrobi to, co musisz zrobić

Amado Saladino
źródło