¿Cómo usar if - else estructura en un archivo por lotes?

136

Tengo una pregunta sobre if - else estructura en un archivo por lotes. Cada comando se ejecuta individualmente, pero no pude usar los bloques "if - else" de manera segura, por lo que estas partes de mi programa no funcionan. ¿Cómo puedo hacer que estas partes funcionen? Gracias.

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
fuente
¿Mi pregunta se lee con claridad? Lo leí línea por línea, pero me parece lado a lado.
epónimo
44
Hola, ¡Bienvenido a Stack Overflow! Para crear un bloque de código, puede resaltar el texto relevante y hacer clic en el {}botón; ayuda a que las publicaciones sean más legibles y evita algunos problemas con el marcado. En respuesta a su pregunta, ¡lo hace ahora! Al escribir una pregunta, hay una vista previa a continuación para que pueda ver cómo se verá una vez publicada.
Ben
1
Así que gracias por tu explicación. Voy a usar este método.
epónimo

Respuestas:

111

Su sintaxis es incorrecta. No puedes usar ELSE IF. Parece que realmente no lo necesitas de todos modos. Simplemente use múltiples IFdeclaraciones:

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

Gran referencia de archivo por lotes: http://ss64.com/nt/if.html

James Hill
fuente
2
Corrígeme si me equivoco, pero no creo que puedas usarlo &&en múltiples ifcondiciones, ¿ves mi sintaxis alternativa?
Bali C
si mi si las condiciones son así: "IF% F% == 0" se ejecuta de forma segura, pero cuando agregué && no se ejecuta. ¿Cómo puedo usar dos condiciones en un if?
epónimo
1
@ programador, mira mi ejemplo. Si tiene múltiples condiciones, useIF condition1 IF condition 2
James Hill
Intenté su respuesta pero no pude ejecutarla, pero intenté nuevamente y modifiqué mi código y se ejecutó. La última situación de alguna parte de mi código es así: IF% F% == 1 IF% C% == 1 (:: copiando el archivo c a d copia "% sourceFile%" "% destinationFile%") ELSE (IF % F% == 1 IF% C% == 0 (:: mover el archivo c a d mover "% sourceFile%" "% destinationFile%")) ELSE (IF% F% == 0 IF% C% == 1 (:: copiando un directorio c de d, / s: boş olanlar hariç, / e: boş olanlar dahil xcopy "% sourceCopyDirectory%" "% destinationCopyDirectory%" / s / e))
epónimo
44
¿Qué quieres decir con que no puedes usar ELSE IF? Funciona bien con Win7. Ver ejemplo: paste2.org/G8tMae92
bryc
56

Creo que en la pregunta y en algunas de las respuestas hay un poco de confusión sobre el significado de este pseudocódigo en DOS: IF A IF BX ELSE Y. No significa IF (A y B) THEN X ELSE Y, pero en hecho significa SI A (SI B ENTONCES X OTRA Y). Si la prueba de A falla, entonces todo el if-else interno será ignorado.

Como se mencionó en una de las respuestas, en este caso solo una de las pruebas puede tener éxito, por lo que no se necesita el 'else', pero por supuesto eso solo funciona en este ejemplo, no es una solución general para hacer if-else.

Hay muchas maneras de evitar esto. Aquí hay algunas ideas, todas son bastante feas, pero bueno, ¡esto es (o al menos era) 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
fuente
Creo que los dos primeros setno necesitan signos de porcentaje; debería serset one=1
Geoff
13

AFAIK no puede hacer un if elselote como puede hacerlo en otros idiomas, tiene que estar anidadoif .

Usando anidados ifsu lote se vería así

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

o como sugirió James, encadene el suyo if, sin embargo, creo que la sintaxis adecuada

IF %F%==1 IF %C%==1(
    ::copying the file c to d
    copy "%sourceFile%" "%destinationFile%"
    )
Bali C
fuente
1
if else, especialmente en lenguajes tipo C, también está anidado if. Tampoco tiene que anidarlos con bloques en archivos por lotes.
Joey
@Joey, no lo sigo del todo. Sé que el else ifcombo es solo un anidado, ifpero no pensé que pudieras usar esas palabras clave juntas en lotes, como puedes hacerlo en lenguajes C.
Bali C
Hmm, todavía no puedo hacer que funcione, pero tomaré tu palabra, sabes de lo que estás hablando, dejaré esta respuesta como una versión larga :)
Bali C
Gracias por sus respuestas, pero ninguna de ellas no se ejecutó en mi código.
epónimo
otro ejemplo: si 1 == 1 (eco 1) más (si 1 == 1 (eco 2) más (eco 3))
JohnP2
1

Creo que puedes usar algo como

if ___ (

do this

) else if ___ (

do this

)
usuario4090570
fuente
27
¿No debería ser la declaración en la segunda condición "hacer eso"?
bvj
77
@bvj No, no, lo entendiste todo mal. Debería ser do fooy do bar.
yyny
Cuando escribes IF (test) (command) ELSE IF (test) (command), estás insinuando IF (test) (command) ELSE (IF (test) (command)). Esto puede funcionar a veces, pero si crees que es una estructura de programación real aceptable en DOS, entonces será una PITA para solucionar problemas cuando falla.
Tim
1

Un poco tarde y tal vez aún sea bueno para las complejas condiciones if, porque me gustaría agregar un parámetro "hecho" para mantener una estructura 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
fuente
0

IF...ELSE IF Las construcciones funcionan muy bien en archivos por lotes, en particular cuando usa solo una expresión condicional en cada línea 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%" )

En su ejemplo, utiliza el IF...AND...IFtipo de construcción, donde se deben cumplir 2 condiciones simultáneamente. En este caso, aún puede usar la IF...ELSE IFconstrucción, pero con paréntesis adicionales para evitar la incertidumbre para la siguiente condición 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%"))

La construcción anterior es 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%"))

La secuencia de procesamiento de los comandos por lotes depende del orden de análisis de CMD.exe . Solo asegúrese de que su construcción siga ese orden lógico y, por regla general, funcionará. Si su script por lotes es procesado por Cmd.exe sin errores, significa que esta es la construcción correcta (es decir, compatible con su versión de OS Cmd.exe), incluso si alguien dijo lo contrario.

sambul35
fuente
0

Aquí está mi código Ejemplo para if..else..if
que hacen lo siguiente

Solicitar al usuario el nombre del proceso

Si el nombre del proceso no es válido,
entonces se escribe al usuario

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

si el nombre del proceso es servicios,
entonces es escribir al usuario

Error : You can't kill the Processor above 

si el nombre del proceso es válido y no servicios,
entonces es escribir al usuario

el proceso ha sido eliminado a través detaskill

así que lo llamé Process killer.bat
Aquí está mi 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
fuente
0

así es como manejé si más si la situación

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

Tenga en cuenta que no es lo mismo que el bloque if-elseif como los otros lenguajes de programación como C ++ o Java, pero hará lo que necesita hacer

Amado Saladino
fuente