Como usar a estrutura if-else em um arquivo em lotes?

136

Eu tenho uma pergunta sobre a estrutura if-else em um arquivo em lotes. Cada comando é executado individualmente, mas eu não poderia usar os blocos "if - else" com segurança para que essas partes do meu programa não funcionem. Como posso fazer essas peças funcionarem? Obrigado.

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%"
    )
epônimo
fonte
Minha pergunta é lida claramente? Eu li linha por linha, mas me parece lado a lado.
epônimo
4
Olá, Bem-vindo ao Stack Overflow! Para criar um bloco de código, você pode destacar o texto relevante e clicar no {}botão; ajuda a tornar as postagens mais legíveis e evita alguns problemas com a marcação. Em resposta à sua pergunta, ele faz agora! Ao escrever uma pergunta, há uma prévia abaixo para que você possa ver como ela ficará depois de publicada.
Ben
1
Então, obrigado pela sua explicação. Eu vou usar esses métodos.
epônimo

Respostas:

110

Sua sintaxe está incorreta. Você não pode usar ELSE IF. Parece que você realmente não precisa disso. Basta usar várias IFinstruções:

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%"
    )

Grande referência de arquivo em lote: http://ss64.com/nt/if.html

James Hill
fonte
2
Corrija-me se estiver errado, mas acho que você não pode usar &&em várias ifcondições. Veja minha sintaxe alternativa.
Bali C
se minhas condições if forem assim: "IF% F% == 0" execute com segurança, mas quando adicionei &&, ele não é executado. Como posso usar duas condições em um if?
epônimo
1
@ programador, veja o meu exemplo. Se você tiver várias condições, useIF condition1 IF condition 2
James Hill
Eu tentei sua resposta, mas não consegui executá-la, mas tentei novamente e modifiquei o código e executei. A última situação de alguma parte do meu código é a seguinte: IF% F% == 1 IF% C% == 1 (:: copiando o arquivo c para d copie "% sourceFile%" "% destinationFile%") ELSE (IF % F% == 1 IF% C% == 0 (:: movendo o arquivo c para d mova "% sourceFile%" "% destinationFile%")) ELSE (IF% F% == 0 IF% C% == 1 (:: copiar um directório c de d, / s: boş olanlar hárico, / e: boş olanlar dahil xcopy "% sourceCopyDirectory%" "% destinationCopyDirectory%" / s / e))
mesmo nome
4
Como assim você não pode usar ELSE IF? Funciona bem no Win7. Veja exemplo: paste2.org/G8tMae92
bryc 30/04/19
56

Penso na pergunta e em algumas das respostas que há um pouco de confusão sobre o significado desse pseudocódigo no DOS: SE A SE BX MAIS Y. Isso não significa SE (A e B) ENTÃO X OU MAIS Y, mas em fato significa SE A (SE B ENTÃO X OU MAIS Y). Se o teste de A falhar, todo o if-else interno será ignorado.

Como uma das respostas mencionadas, neste caso, apenas um dos testes pode ser bem-sucedido, de modo que o 'else' não é necessário, mas é claro que só funciona neste exemplo, não é uma solução geral para se fazer o else.

Existem muitas maneiras de contornar isso. Aqui estão algumas idéias, todas são bastante feias, mas ei, isso é (ou pelo menos foi) o 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
fonte
Eu acho que os dois primeiros setnão precisam de sinais de porcentagem; deveria serset one=1
Geoff
13

Como você não pode fazer um if elselote como em outros idiomas, ele deve ser aninhado if.

Usando aninhados if, seu lote seria semelhante

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%"
                )
            )
        )
    )

ou, como James sugeriu, encadeie os seus if, no entanto, acho que a sintaxe apropriada é

IF %F%==1 IF %C%==1(
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    )
Bali C
fonte
1
if else, especialmente em idiomas do tipo C, também é apenas um aninhado if. Você também não precisa aninhá-los com blocos em arquivos em lotes.
Joey
@ Joey eu não sigo muito bem. Eu sei que a else ifcombinação é apenas um aninhado, ifmas não achei que você pudesse usar essas palavras-chave juntas em lote, como é possível nos idiomas C.
Bali C
Hmm eu ainda não pode obtê-lo para o trabalho, mas eu vou levar sua palavra para ela, você sabe o que você está falando, eu vou deixar esta resposta como uma versão longa :)
Bali C
Obrigado por suas respostas, mas nenhuma delas não foi executada no meu código.
homônimo
outro exemplo: se um == 1 (echo 1) o resto (se um == 1 (echo 2) outra (echo 3))
JohnP2
1

Eu acredito que você pode usar algo como

if ___ (

do this

) else if ___ (

do this

)
user4090570
fonte
27
A declaração na segunda condição não deveria ser "faça isso"?
BVJ
7
@bvj Não, não, você entendeu tudo errado. Deveria ser do fooe do bar.
Yyny 3/04
Quando você escreve IF (test) (command) ELSE IF (test) (command), está implicando IF (test) (command) ELSE (IF (test) (command)). Às vezes, isso pode funcionar, mas se você acredita que é uma estrutura de programação real aceitável no DOS, será uma PITA para solucionar problemas quando falhar.
Tim
1

Um pouco atrasado e talvez ainda seja bom para condições if complexas, porque eu gostaria de adicionar um parâmetro "done" para manter uma estrutura 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
fonte
0

IF...ELSE IF construções funcionam muito bem em arquivos em lote, principalmente quando você usa apenas uma expressão condicional em cada linha 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%" )

No seu exemplo, você usa IF...AND...IFtype construct, em que 2 condições devem ser atendidas simultaneamente. Nesse caso, você ainda pode usar a IF...ELSE IFconstrução, mas com parênteses extras para evitar incertezas para a próxima condição 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%"))

A construção acima é equivalente a:

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%"))

A sequência de processamento dos comandos em lote depende da ordem de análise do CMD.exe . Apenas certifique-se de que sua construção siga essa ordem lógica e, como regra geral, funcionará. Se o script em lote for processado pelo Cmd.exe sem erros, significa que esta é a construção correta (isto é, suportada pela versão do OS Cmd.exe), mesmo se alguém disser o contrário.

sambul35
fonte
0

Aqui está o meu código Exemplo para if..else..if
que faz o seguinte

Solicitar ao usuário o Nome do Processo

Se o nome do processo for inválido
, será gravado no usuário

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

se o nome do processo for services
, será gravado no usuário

Error : You can't kill the Processor above 

se o nome do processo for válido e não serviços
, será gravado no usuário

o processo foi morto viataskill

então eu o chamei Process killer.bat
Aqui está o meu código:

@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
fonte
0

aqui está como eu lidei se mais se situação

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

Observe que não é o mesmo bloco if-elseif que as outras linguagens de programação como C ++ ou Java, mas fará o que você precisa fazer

Amado Saladino
fonte