Crear carpeta con lote pero solo si aún no existe

440

¿Alguien puede decirme cómo hacer lo siguiente en un script por lotes de Windows? ( *.bat):

  • Cree una carpeta solo si aún no existe

Con más detalle, quiero crear una carpeta nombrada VTSen la C:\unidad, pero solo si esa carpeta aún no existe. No quiero sobrescribir el contenido de la carpeta si ya existe y se ejecuta el lote.

Cuenta
fuente
2
Qué tal esto ? if not exist "%Folder%" mkdir "%New-Folder%"
scientist_7

Respuestas:

622

Simplemente use esto: if not exist "C:\VTS\" mkdir C:\VTScreará un directorio solo si la carpeta no existe.

Tenga en cuenta que esta prueba de existencia devolverá verdadero solo si VTS existe y es un directorio. Si no está allí, o está allí como un archivo, se ejecutará el comando mkdir y debería provocar un error. Es posible que desee verificar si VTS también existe como un archivo.

El que responde
fuente
77
Excepto que está mal. Debe verificar el dispositivo NUL, de lo contrario no funcionará. Vea mi respuesta tres años antes que esta.
Martin Schapendonk
@ MartininSchapendonk Esto funciona en Windows 7 y Windows Server 2012 por lo que puedo ver en las pruebas, y me sorprendería mucho si no funciona al menos hasta XP y hasta Windows 10. ¿Puede proporcionar las condiciones cuando esto no funciona?
jpmc26
12
@ jpmc26 probar para NUL es asegurarse de que prueba un directorio. De lo contrario, la condición podría evaluarse como verdadera, incluso si se trata de un archivo normal. Esa es la diferencia.
Martin Schapendonk
3
@MartinSchapendonk ¿Es suficiente agregar una barra inclinada final para eso? Eso parece distinguir entre archivos y directorios correctamente, pero hay una debilidad en que si el archivo no se detecta, la creación del directorio fallará. Sospecho que esto también es un problema con las pruebas NUL.
jpmc26
66
@ jpmc26 Tiene razón, una barra inclinada final hace el trabajo y en realidad es preferible ya que funciona con comillas (lo que le permite tener espacios en la ruta del directorio). Para distinguir entre cualquiera de los archivos / directorios, esto va a funcionar: if exist "a" if not exist "a\" (echo "it's a file") else (echo "it's a dir"). Acerca de su última oración, sospecho que algo está mal con su archivo por lotes en otro lugar.
Marc.2377
221
if exist C:\VTS\NUL echo "Folder already exists"

if not exist C:\VTS\NUL echo "Folder does not exist"

Consulte también https://support.microsoft.com/en-us/kb/65994

(Actualización 7 de marzo de 2018; el artículo de Microsoft está caído, archivar en https://web.archive.org/web/20150609092521/https://support.microsoft.com/en-us/kb/65994 )

Martin Schapendonk
fuente
12
Personalmente, preferiría esto, ya que no establece% errorlevel% cuando el directorio ya existe (la respuesta del Agente_9191 devuelve un código de error de 1)
csauve 18/06/12
1
También es agradable y genérico y se puede aplicar a cualquier otra acción que desee realizar condicionalmente :)
John Humphreys - w00te
3
@YouHaveaBigEgo NULestá con una L.
Martin Schapendonk
1
El enlace ya no funciona, pero hay una copia en el Archivo de Internet
fernio
3
En realidad, aunque esta respuesta es excelente, no responde a la pregunta "crear un directorio" :)
Jean-Francois T.
55

Simplemente llame mkdir C:\VTSsin importar qué. Simplemente informará que el subdirectorio ya existe.

Editar: como otros han notado, esto establece el% ERRORLEVEL% si la carpeta ya existe. Si su lote (o cualquier proceso que lo llame) no se preocupa por el nivel de error, este método funciona bien. Dado que la pregunta no mencionaba cómo evitar el nivel de error, esta respuesta es perfectamente válida. Satisface las necesidades de crear la carpeta si no existe, y no sobrescribe el contenido de una carpeta existente. De lo contrario, siga la respuesta de Martin Schapendonk .

Agent_9191
fuente
20
Este es un mal comportamiento debido a un mensaje / advertencia de error inesperado.
SeriousM
10
Llamar a algo "perfectamente válido" cuando viola las mejores prácticas es intelectualmente deshonesto. Como otro ejemplo: cuando alguien le pregunta cómo evitar un determinado problema de seguridad específico, su respuesta no debe ser "ejecutar la computadora como administrador", incluso si la pregunta no especifica explícitamente el impacto mínimo de seguridad como requisito previo. :-)
Jouni Heikniemi
2
@JouniHeikniemi s / mejores prácticas / Preferencias personales de Jouni
dss539
44
No hay nada malo con Errorlevel o errno. Son paradigmas de mensajes de error específicos de la plataforma, y ​​funcionan para el propósito para el que fueron creados. Pero no importa cuál sea la plataforma o el enfoque de mensajería, no recomendaría el patrón "intente hacer esto y recuperarse si falla" cuando puede evitar fácilmente, y por lo tanto documentar legiblemente, el caso de error común. Por lo tanto, encuentro que los enfoques de estilo "si no existe" son superiores. Pero no quiero ni me importa profundizar demasiado en un debate sobre la formación de las mejores prácticas. No tenía intención de ofender a nadie, solo quería aclarar mi voto negativo.
Jouni Heikniemi
44
El problema con simplemente ignorar el error es que no sabes por qué falló. Podría haber fallado porque el directorio ya existía, porque el usuario no tiene permisos en ese directorio, porque la ruta principal no existía o porque el disco falló. "Crear si no existe" debería fallar en todos los casos, excepto en el primero. Sin embargo, esta respuesta produce un error en todos los casos. Es por eso que no es adecuado para un script por lotes. -1
jpmc26
38
mkdir C:\VTS 2> NUL

crear una carpeta llamada VTSy salida A subdirectory or file TEST already existsa NUL.

o

(C:&(mkdir "C:\VTS" 2> NUL))&

cambie la letra de unidad a C:, mkdirerror de salida ay NULejecute el siguiente comando.

3 años2late
fuente
¿Hay alguna manera de hacer que esto funcione en PowerShell? No parece admitir NULcomo un archivo de salida.
Aaron Franke
30
set myDIR=LOG
IF not exist %myDIR% (mkdir %myDIR%)
Robie
fuente
1
Como otros han señalado y es posible que haya visto en la respuesta mejor calificada, esto no funciona si tiene un archivo llamado log. Es una diferencia sutil, pero dará lugar a errores difíciles de encontrar en sus scripts.
Abel
20

Lo uso de esta manera, debe colocar una barra diagonal inversa al final del nombre del directorio para evitar que ese lugar exista en un archivo sin extensión con el mismo nombre que el directorio que especificó, nunca use "C: \ VTS" porque puede contener un archivo existe con el nombre "VTS" guardado en la partición "C:" , la forma correcta es usar "C: \ VTS \" , verifique la barra invertida después del VTS , así que es la forma correcta.

@echo off
@break off
@title Create folder with batch but only if it doesn't already exist - D3F4ULT
@color 0a
@cls

setlocal EnableDelayedExpansion

if not exist "C:\VTS\" (
  mkdir "C:\VTS\"
  if "!errorlevel!" EQU "0" (
    echo Folder created successfully
  ) else (
    echo Error while creating folder
  )
) else (
  echo Folder already exists
)

pause
exit
D3F4ULT
fuente
3
Lo que es particularmente interesante de su solución es que utiliza !errorlevel!, es decir, la expansión retrasada. De lo contrario, la variable ERRORLEVELse analizaría antes de ingresar la primera if(es decir, en el momento del análisis). Ahora se analiza en tiempo de ejecución, por lo que puede capturar el resultado de mkdir. También tiene razón en eso, a pesar de que prueba la existencia, aún debe probar el éxito (piense: error de acceso denegado, por ejemplo). Muy buena solución en comparación con los demás, +10 !!!
Abel
17

Puedes usar:

if not exist "C:\VTS\" mkdir "C:\VTS"

También puede expandir el código para reemplazar los archivos esperados que faltan.

if not exist "C:\VTS\important.file" echo. > "C:\VTS\important.file"

fuente
0

Creé esto para mi script que uso en mi trabajo para eyebeam.

:CREATES A CHECK VARIABLE

set lookup=0

:CHECKS IF THE FOLDER ALREADY EXIST"

IF EXIST "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\" (set lookup=1)

:IF CHECK is still 0 which means does not exist. It creates the folder

IF %lookup%==0 START "" mkdir "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\"
Winston
fuente