windows 如何测试路径是Windows批处理文件中的文件还是目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8666225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 09:03:47  来源:igfitidea点击:

How to test if a path is a file or directory in Windows batch file?

windowsbatch-file

提问by aaron

I searched here, found someone using this

我在这里搜索,发现有人使用这个

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

but didn't work, when %1==c:\this is a file with spaces.csproj, the test still success, which means it will still be treated as a folder!!!

但是没有%1==c:\this is a file with spaces.csproj成功,当,测试仍然成功,这意味着它仍然会被视为一个文件夹!!!

anyone knows the answer, i guess this is a very common problem and Windows has existed for many many years, it should have a very simple solution....

任何人都知道答案,我想这是一个非常普遍的问题,Windows 已经存在很多年了,它应该有一个非常简单的解决方案....

回答by dbenham

I know the if exist path\nultest for a folder used to work on MS-DOS. I don't know if it was broken with the introduction of long file names.

我知道if exist path\nul用于在 MS-DOS 上工作的文件夹的测试。不知道是不是因为引入了长文件名而被破坏了。

I knew that if exist "long path\nul"does not work on Windows batch. I did not realize until today that if exist path\nulworks on Vista and beyond as long as path is in the short 8.3 form.

我知道这if exist "long path\nul"不适用于 Windows 批处理。直到今天,我才意识到if exist path\nul只要路径是简短的 8.3 形式,它就可以在 Vista 及更高版本上运行。

The original code appears to work on Vista. It seems like it should work on XP as well, but I believe the following XP bug is getting in the way: Batch parameter %~s1 gives incorrect 8.3 short name.

原始代码似乎适用于 Vista。看起来它也应该在 XP 上工作,但我相信以下 XP 错误正在妨碍:批处理参数 %~s1 给出了不正确的 8.3 短名称

The original code does not need the FOR loop, it could simply use %~s1

原始代码不需要 FOR 循环,它可以简单地使用 %~s1

Here is a variation that fully classifies a path as INVALID, FILE or FOLDER. It works on Vista, but does NOT work on XP because of the %~s1bug. I'm not sure how it performs on MS-DOS.
EDIT 2015-12-08: There are a number of Windows situations where this fails

这是将路径完全分类为无效、文件或文件夹的变体。它适用于 Vista,但由于该%~s1错误而不适用于 XP 。我不确定它在 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%

I believe this variation will work with nearly all versions of Microsoft batch, including MS-DOS and XP. (it obviously won't work on early versions of DOS that don't support PUSHD)

我相信这种变化适用于几乎所有版本的 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%

UPDATE 2014-12-26

更新 2014-12-26

I'm pretty sure the following will work on all versions of Windows from XP onward, but I have only tested on Win 7.
Edit 2015-12-08: This can fail on network drives because the folder test can falsely report a file as a folder

我很确定以下内容适用于从 XP 开始的所有版本的 Windows,但我只在 Win 7 上进行过测试。
编辑 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
)

UPDATE 2015-12-08

更新 2015-12-08

Finally - a test that truly should work on any Windows version from XP onward, including with network drives and UNC paths

最后 - 真正适用于 XP 以后的任何 Windows 版本的测试,包括网络驱动器和 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
)

Note- This technique is intended to be used for a path without any wildcards (a single specific file or folder). If the provided path includes one or more wildcards, then it provides the result for the first file or folder that the file system encounters. Identical directory structures may give different sort order results depending on the underlying file system (FAT32, NTFS, etc.)

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

回答by Vaandu

I just tried in this way. Hope this helps.

我就是这样试的。希望这可以帮助。

@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

回答by Arun

The /ad option for "dir" command lists folders, /b option for bare. Assuming you have checks for the existence of file in place, use:

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

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

回答by fluoresc

For a 1 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)

e.g. change C:\Windowsto C:\Windows\Notepad.exe

例如更改C:\WindowsC:\Windows\Notepad.exe

-Sorry Arun, dbenham, didn't read yours! Same as..

- 抱歉阿伦,dbenham,没有读你的!与...一样..

回答by andronoid

This solutioncombines the file attribute parameter extension(%~a1) with variable substring extraction(%variable:~0,1%):

该解决方案将文件属性参数扩展名( %~a1) 与变量子字符串提取( %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

Output:

输出:

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

回答by Kevin Fegan

Previously, I used the "\nul"method, but for a long time now, I have used "\*"to test if an existing filespec is a folder or a file. As far as I know, it works on all versions of Windows, from Windows 95 (and perhaps earlier versions) through all current Windows versions.

以前,我用过这个"\nul"方法,但现在很长一段时间,我都用来"\*"测试现有的filespec是文件夹还是文件。据我所知,它适用于所有版本的 Windows,从 Windows 95(可能还有更早的版本)到所有当前的 Windows 版本。

So, as with other methods, first test if the file exists. Then, to see if it's a "Folder", test it with: if exist "%fspec%\*":

因此,与其他方法一样,首先测试文件是否存在。然后,要查看它是否是“文件夹”,请使用以下命令对其进行测试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

For example:

例如:

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

The output for this is:

这个输出是:

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