2011-12-29 15 views
9

busqué aquí, encontraron a alguien que utiliza este¿Cómo probar si una ruta es un archivo o directorio en el archivo por lotes de Windows?

set is_dir=0 
for %%i in ("%~1") do if exist "%%~si"\nul set is_dir=1 

pero no funcionó, cuando %1==c:\this is a file with spaces.csproj, la prueba sigue siendo el éxito, lo que significa que todavía será tratada como una carpeta !!!

alguien sabe la respuesta, creo que esto es un problema muy común y Windows ha existido durante muchos años, debe tener una solución muy simple ....

+1

Es el pregunta realmente acerca de ms-dos, o acerca de un símbolo del sistema en Windows? ¿Y qué versión? – wimh

+0

mi entorno de prueba son windows 7 x64 y Windows XP, no probé en otras plataformas. Gracias. – aaron

Respuesta

20

sé la prueba if exist path\nul para una carpeta que se utiliza para trabajar en MS-DOS. No sé si se rompió con la introducción de nombres de archivo largos.

Sabía que if exist "long path\nul" no funciona en el lote de Windows. No me di cuenta hasta hoy que if exist path\nul funciona en Vista y más allá, siempre y cuando el camino esté en el formato corto 8.3.

Parece que el código original funciona en Vista. Parece que también debería funcionar en XP, pero creo que el siguiente error de XP se interpone en el camino: Batch parameter %~s1 gives incorrect 8.3 short name.

El código original no necesita el bucle FOR, simplemente podría utilizar %~s1

Aquí es una variación que clasifica completamente un camino no son válidos, archivo o carpeta. Funciona en Vista, pero NO funciona en XP debido al error %~s1. No estoy seguro de cómo funciona en MS-DOS.
EDITAR 12/08/2015: Hay una serie de situaciones de Windows, donde esta falla

@echo off 
if not exist "%~1" (set "type=INVALID") else if exist %~s1\nul (set "type=FOLDER") else (set "type=FILE") 
@echo "%~1" = %type% 

creo que esta variación trabajará con casi todas las versiones de Microsoft por lotes, incluyendo MS-DOS y Windows XP . (Es obvio que no va a trabajar en las primeras versiones de DOS que no soportan PUSHD)

@echo off 
if exist "%~1" (2>nul pushd "%~1" && (popd&set "type=FOLDER") || set "type=FILE") else set "type=INVALID" 
echo "%~1" = %type% 

ACTUALIZACIÓN 2014-12-26

Estoy bastante seguro de que el siguiente trabajo en todas las versiones de Windows desde XP en adelante, pero solo he probado en Win 7.
Editar 12.08.2015: Este puede fallar en unidades de red porque la prueba carpeta puede reportar falsamente un archivo como una carpeta

@echo off 
if exist %1\ (
    echo %1 is a folder 
) else if exist %1 (
    echo %1 is a file 
) else (
    echo %1 does not exist 
) 

ACTUALIZACIÓN 2015-12-08

Finalmente, una prueba que realmente debería funcionar en cualquier versión de Windows desde XP en adelante, incluso con unidades de red y rutas UNC

for /f "tokens=1,2 delims=d" %%A in ("-%~a1") do if "%%B" neq "" (
    echo %1 is a folder 
) else if "%%A" neq "-" (
    echo %1 is a file 
) else (
    echo %1 does not exist 
) 
+0

Usaré esto, ¡gracias! – aaron

+0

@dbenham: Nota breve sobre la actualización de 2014, ¿no sería una buena idea poner las partes '% 1 \' y '% 1' entre comillas? – zb226

+1

@ zb226 - No, no es necesario agregar comillas adicionales. El argumento ya debería ser citado, de lo contrario no podrías haberlo recibido en primer lugar. Tenga en cuenta que no está de más tener el '\' fuera de las comillas. '" c: \ ruta \ "' y '" c: \ ruta "\' son equivalentes. Si realmente desea agregar explícitamente sus propias comillas, debe usar '"% ~ 1 "' y '"% ~ 1 \ "'. – dbenham

6

he intentado de esta manera. Espero que esto ayude.

@ECHO OFF 
SET CURR_DIR=%CD% 
SET IS_DIR=0 
CD %1% 
IF "%ERRORLEVEL%"=="0" SET IS_DIR=1 
CD %CURR_DIR% 
ECHO IS DIRECTORY %IS_DIR% 

Salida:

D:\Work\Stand alone Java classes>test.bat D:\Work\Training 
IS DIRECTORY 1 

D:\Work\Stand alone Java classes>test.bat D:\Work\Training\SRT.txt 
The directory name is invalid. 
IS DIRECTORY 0 
+0

Genial, gracias! Y lo hice un poco más corto: 'PUSHD% 1 2> NUL && SET IS_DIR = 1 || SET IS_DIR = 0 & POPD' – aaron

1

La opción/ad para el comando "dir" enumera las carpetas,/la opción de desnudo. Asumiendo que tiene comprueba la existencia de archivo en su lugar, utilizan:

dir /ad /b ChangeThisToYourFilename 1> NUL 2> NUL 
if %ERRORLEVEL% EQU 0 (
    echo is a file 
) else (
    echo is NOT a file 
) 
+0

Funciona si cambia el texto para leer 'es una carpeta' o 'no es una carpeta'. Forma interesante de hacerlo No es intuitivo, pero funciona porque una carpeta siempre tiene el. y ... directorios disponibles dentro de. Un archivo nunca lo hace – dbenham

+0

Sintaxis más simple: la misma solución: 'dir/ad/b" somePath "1> nul 2> nul && (echo es una carpeta) || (echo no es una carpeta) ' – dbenham

+0

si la carpeta contiene muchas subcarpetas, ¿puede llevar un tiempo ejecutarlas? – aaron

1

Para un 1 liner:

dir /a:d /b C:\Windows 2>&1 | findstr /i /n /c:"File Not Found">nul && (@echo. Im a file) || (@echo. Im a folder) 

por ejemplo cambiar C:\Windows a C:\Windows\Notepad.exe

-Lo sentimos, Arun, dbenham, no leyó el tuyo! Igual que ...

+0

hmm, esto podría tener un problema de localización? – aaron

+0

Sin findstr es aún más corto: 'dir/a: d/b C: \ Windows 2> nul> nul && (@echo. Im a file) || (@echo. Soy una carpeta) ' – Radon8472

0

Anteriormente, utilicé el método "\nul", pero durante mucho tiempo, he usado "\*" para probar si una especificación de archivos existente es una carpeta o un archivo. Hasta donde yo sé, funciona en todas las versiones de Windows, desde Windows 95 (y quizás versiones anteriores) a través de todas las versiones actuales de Windows.

Por lo tanto, como con otros métodos, primero compruebe si el archivo existe. A continuación, para ver si se trata de una "carpeta", prueba con: if exist "%fspec%\*":

if not exist "%fspec%" goto :NotExistOrInvalid 

rem "%fspec%" is "Valid" and is either a "Folder", or a "File". 
if  exist "%fspec%\*" goto :IsValidAndIsAFolder 

rem "%fspec%" is a "File" (a "Regular File" or a Shortcut/Link). 
goto :IsValidAndIsAFile 

Por ejemplo:

set "fspec=XYZ:%perlpath%" 
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem Invalid, goto :NotExistOrInvalid 

set "fspec=%perlpath%" 
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem goto :NotExistOrInvalid 

rem "%fspec%" Is a "Valid" filespec and is either a "Folder", or a "File". 
if exist "%fspec%\*" (echo "%fspec%" is a "Folder".) else echo "%fspec%" is a "File". 

set "fspec=%perlpath%\perl.exe" 
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem Invalid, goto :NotExistOrInvalid 

rem "%fspec%" Is a "Valid" filespec and is either a "Folder", or a "File". 
if exist "%fspec%\*" (echo "%fspec%" is a "Folder".) else echo "%fspec%" is a "File". 

La salida de esto es:

"XYZ:F:\usr\perl\bin": Invalid or not found 
"F:\usr\perl\bin" is a "Folder". 
"F:\usr\perl\bin\perl.exe" is a "File". 
Cuestiones relacionadas