如何在Windows批处理文件中测试路径是否是文件或目录?

bttbmeg0  于 2023-05-08  发布在  Windows
关注(0)|答案(6)|浏览(277)

我搜了这里发现有人在用这个

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

但没有工作,当%1==c:\this is a file with spaces.csproj,测试仍然成功,这意味着它仍然会被视为一个文件夹!!!
任何人都知道答案,我猜这是一个非常普遍的问题和Windows已经存在了很多很多年,它应该有一个非常简单的解决方案。

cs7cruho

cs7cruho1#

我知道if exist path\nul测试用于在MS-DOS上工作的文件夹。我不知道它是否被打破与引入长文件名。
我知道if exist "long path\nul"在Windows批处理上不起作用。我直到今天才意识到,只要path是短的8.3形式,if exist path\nul就可以在Vista和更高版本上工作。
原始代码似乎在Vista上工作。看起来它也应该能在XP上工作,但我相信下面的XP bug会妨碍它:Batch parameter %~s1 gives incorrect 8.3 short name
原始代码不需要FOR循环,它可以简单地使用%~s1
下面是一个变体,它将路径完全分类为INVALID、FILE或FOLDER。它在Vista上工作,但在XP上不工作,因为X1 M4 N1 X错误。我不知道它在MS-DOS上的表现如何。

编辑2015-12-08:在许多Windows情况下,这会失败

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

我相信这个变体将与几乎所有版本的Microsoft批处理,包括MS-DOS和XP。(它显然不会在不支持PUSHD的早期版本的DOS上工作)

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

更新2014-12-26

我很确定以下内容可以在XP以后的所有版本的Windows上运行,但我只在Win7上进行了测试。

编辑2015-12-08:这可能会失败的网络驱动器,因为文件夹测试可以错误地报告一个文件作为文件夹

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

更新2015-12-08

最后-一个测试,真正应该工作在任何Windows版本从XP开始,包括与网络驱动器和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
)

注意-此技术旨在用于没有任何通配符的路径(单个特定文件或文件夹)。如果提供的路径包括一个或多个通配符,则它提供文件系统遇到的第一个文件或文件夹的结果。相同的目录结构可能会根据底层文件系统(FAT32、NTFS等)给予不同的排序顺序结果。

xfyts7mz

xfyts7mz2#

我只是用这种方式尝试。希望这能帮上忙。

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

输出:

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
9bfwbjaz

9bfwbjaz3#

“dir”命令的/ad选项列出文件夹,/B选项列出空文件夹。假设您已检查文件是否存在,请用途:

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

p4rjhz4m4#

对于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)

例如,将C:\Windows更改为C:\Windows\Notepad.exe

  • 对不起,阿伦,德本汉姆,没有读你的!和。
p1tboqfb

p1tboqfb5#

以前,我使用"\nul"方法,但现在很长一段时间,我都使用"\*"来测试现有的filespec是文件夹还是文件。据我所知,它适用于所有版本的Windows,从Windows 95(也许还有更早的版本)到所有当前的Windows版本。
因此,与其他方法一样,首先测试文件是否存在。然后,要查看它是否是一个“文件夹”,请使用以下方法进行测试: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

例如:

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

其输出为:

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

xuo3flqw6#

This solution将文件属性parameter extension%~a1)与variable substring extraction%variable:~0,1%)组合:

@ECHO OFF

CALL :is_directory C:\Windows
CALL :is_directory C:\MinGW\share\doc\mingw-get\README
CALL :is_directory C:\$Recycle.Bin
CALL :is_directory "C:\Documents and Settings"
CALL :is_directory "%LOGONSERVER%\C$\Users\All Users"

GOTO :EOF

:is_directory
    SETLOCAL
    SET file_attribute=%~a1
    IF "%file_attribute:~0,1%"=="d" (
        ECHO %file_attribute% %1 is a directory
    ) ELSE (
        ECHO %file_attribute% %1 is NOT a directory
    )
    ENDLOCAL
    GOTO :EOF

输出:

d-------- C:\Windows is a directory
--a------ C:\MinGW\share\doc\mingw-get\README is NOT a directory
d--hs---- C:\$Recycle.Bin is a directory
d--hs---l "C:\Documents and Settings" is a directory
d--hs---l "\\MYCOMPUTER\C$\Users\All Users" is a directory

相关问题