2011-12-29 31 views
9

Tôi đã tìm kiếm ở đây, tìm thấy một người nào đó sử dụng nàyLàm thế nào để kiểm tra nếu một đường dẫn là một tập tin hoặc thư mục trong tập tin thực thi Windows?

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

nhưng không hiệu quả, khi %1==c:\this is a file with spaces.csproj, kiểm tra vẫn thành công, có nghĩa là nó vẫn sẽ được coi như một thư mục !!!

ai biết câu trả lời, tôi đoán đây là một vấn đề rất phổ biến và Windows đã tồn tại nhiều trong nhiều năm, cần có một giải pháp rất đơn giản ....

+1

là câu hỏi của bạn thực sự về ms-dos, hoặc về một dấu nhắc lệnh trong cửa sổ? Và phiên bản nào? – wimh

+0

môi trường thử nghiệm của tôi là cả windows 7 x64 và windows xp, tôi không thử trên các nền tảng khác. cảm ơn. – aaron

Trả lời

20

Tôi biết các thử nghiệm if exist path\nul cho một thư mục đã từng làm việc trên MS-DOS. Tôi không biết nếu nó bị hỏng với việc giới thiệu tên tập tin dài.

Tôi biết rằng if exist "long path\nul" không hoạt động trên lô Windows. Tôi đã không nhận ra cho đến ngày hôm nay rằng if exist path\nul hoạt động trên Vista và hơn thế nữa miễn là đường dẫn ở dạng ngắn 8,3.

Mã gốc dường như hoạt động trên Vista. Có vẻ như nó cũng hoạt động trên XP, nhưng tôi tin rằng lỗi XP sau đây đang cản trở: Batch parameter %~s1 gives incorrect 8.3 short name.

Mã gốc không cần FOR loop, nó chỉ đơn giản có thể sử dụng %~s1

Đây là một biến thể hoàn toàn phân loại một con đường như INVALID, file hoặc thư mục. Nó hoạt động trên Vista, nhưng không hoạt động trên XP vì lỗi %~s1. Tôi không chắc nó hoạt động như thế nào trên MS-DOS.
EDIT 2015/12/08: Có một số tình huống của Windows, nơi này không thành công

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

Tôi tin rằng sự thay đổi này sẽ làm việc với hầu hết các phiên bản của Microsoft hàng loạt, bao gồm MS-DOS và XP . (Nó rõ ràng sẽ không hoạt động trên các phiên bản đầu tiên của hệ điều hành DOS không hỗ trợ pushd)

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

CẬP NHẬT 2014-12-26

Tôi chắc rằng những điều sau đây sẽ làm việc trên tất cả các phiên bản của Windows từ XP trở đi, nhưng tôi chỉ thử nghiệm trên Win 7.
Sửa 2015/12/08: Đây có thể thất bại trên ổ đĩa mạng vì kiểm tra thư mục sai có thể báo cáo một tập tin như một thư mục

@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 
) 

CẬP NHẬT 2015-12-08

Cuối cùng - một thử nghiệm thực sự sẽ hoạt động trên bất kỳ phiên bản Windows nào từ XP trở đi, kể cả với các ổ đĩa mạng và đường dẫn 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

Tôi sẽ sử dụng điều này, cảm ơn! – aaron

+0

@dbenham: Lưu ý ngắn về bản cập nhật năm 2014, bạn có nên đặt các phần '% 1 \' và '% 1' vào dấu ngoặc kép không? – zb226

+1

@ zb226 - Không, thêm dấu ngoặc kép bổ sung là không cần thiết. Các đối số nên đã được trích dẫn, nếu không bạn không thể nhận được nó ở nơi đầu tiên. Lưu ý rằng nó không làm tổn thương để có '\' bên ngoài của bất kỳ dấu ngoặc kép nào. '" c: \ path \ "' và '" c: \ path "\' là tương đương. Nếu bạn thực sự muốn thêm dấu ngoặc kép của riêng mình, thì bạn phải sử dụng '"% ~ 1 "' và '"% ~ 1 \ "'. – dbenham

6

Tôi chỉ cố gắng theo cách này. Hi vọng điêu nay co ich.

@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% 

Output:

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

Tuyệt vời, cảm ơn! Và tôi đã làm cho nó một lứa ngắn hơn: 'PUSHD% 1 2> NUL && SET IS_DIR = 1 || SET IS_DIR = 0 & POPD' – aaron

1

Tùy chọn/ad cho lệnh "dir" liệt kê các thư mục,/b tùy chọn để trống. Giả sử bạn có kiểm tra cho sự tồn tại của tập tin tại chỗ, sử dụng:

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

Hoạt động nếu bạn thay đổi văn bản cần đọc 'là một thư mục' hoặc 'không phải là một thư mục'. Cách thú vị để làm điều đó. Không trực quan, nhưng hoạt động vì một thư mục luôn có. và .. thư mục có sẵn bên trong. Một tập tin không bao giờ. – dbenham

+0

Cú pháp đơn giản - cùng một giải pháp: 'dir/ad/b" somePath "1> nul 2> nul && (echo là một thư mục) || (echo không phải là một thư mục) ' – dbenham

+0

nếu thư mục chứa nhiều thư mục con, quá trình này có thể mất một lúc để thực thi? – aaron

1

Đối với một liner 1:

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

ví dụ thay đổi C:\Windows đến C:\Windows\Notepad.exe

-Xin lỗi Arun, dbenham, không đọc của bạn! Giống như ..

+0

hmm, điều này có thể có vấn đề về bản địa hóa? – aaron

+0

Nếu không tìm thấy nó thậm chí ngắn hơn: 'dir/a: d/b C: \ Windows 2> nul> nul && (@echo. Im tệp) || (@echo. Im một thư mục) ' – Radon8472

0

Trước đây, tôi đã sử dụng phương thức "\nul", nhưng trong một thời gian dài, tôi đã sử dụng "\*" để kiểm tra xem tệp hiện có là một thư mục hay tệp. Theo như tôi biết, nó hoạt động trên tất cả các phiên bản của Windows, từ Windows 95 (và có lẽ phiên bản cũ hơn) thông qua tất cả các phiên bản Windows hiện tại.

Vì vậy, như với các phương pháp khác, trước tiên hãy kiểm tra xem tệp có tồn tại không. Sau đó, để xem nếu nó là một "Folder", thử nghiệm nó với: 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 

Ví dụ:

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". 

Kết quả của việc này là:

"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". 
Các vấn đề liên quan