如何在批处理脚本中测试文件是否为目录?
有没有办法找出文件是否是目录?
我在变量中有文件名。在Perl中,我可以这样做:
if(-d $var) { print "it's a directory\n" }
解决方案
我们可以这样做:
IF EXIST %VAR%\NUL ECHO It's a directory
但是,这仅适用于名称中没有空格的目录。当我们在引号周围加上变量以处理空格时,它将停止工作。要处理带空格的目录,请按以下方式将文件名转换为短8.3格式:
FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory
%%〜si
将%% i`转换为8.3文件名。要查看我们可以使用" FOR"变量执行的所有其他技巧,请在命令提示符下输入" HELP FOR"。
(请注意,上面给出的示例采用的格式可以在批处理文件中使用。要使其在命令行上正常工作,请在两个位置均将" %%"替换为"%"。)
基于标题为"批处理文件如何测试目录的存在"的文章,它"并不完全可靠"。
但是我刚刚测试了这个:
@echo off IF EXIST %1\NUL goto print ECHO not dir pause exit :print ECHO It's a directory pause
它似乎有效
NUL技术似乎仅适用于8.3兼容文件名。
(换句话说," D:\ Documents and Settings"是"坏",而" D:\ DOCUME〜1"是"好")
我认为当目录名称中有空格(例如"文档和设置")时,使用" NUL"技术会有些困难。
我正在使用Windows XP Service Pack 2,并从%SystemRoot%\ system32 \ cmd.exe启动cmd提示符
以下是一些DID不起作用以及对我有用的示例:
(这些都是在交互式提示下"实时"完成的演示。我认为在尝试在脚本中对其进行调试之前,我们应该使一切正常工作。)
此DID不起作用:
`D:\ Documents and Settings>如果存在,则" D:\ Documents and Settings \ NUL"回显是。
此DID不起作用:
D:\ Documents and Settings>是否存在D:\ Documents and Settings \ NUL echo是
这确实起作用(对我而言):
D:\ Documents and Settings> cd ..
D:\> REM获得文件的短8.3名称
D:\> dir / x
`驱动器D中的卷没有标签。
卷序列号是34BE-F9C9
D的目录:\
2008年9月25日05:09 PM <DIR>09/25/2008 05:14 PM <DIR> 200809〜1.25 2008.09.25
09/23/2008 03:44 PM <DIR> BOOST_〜3 boost_repo_working_copy
09/02/2008 02:13 PM 486,128 CHROME〜1.EXE ChromeSetup.exe
02/14/2008 12:32 PM <DIR> cygwin
看这里!!!! 2008-09-25 08:34 <DIR> DOCUME〜1文档和设置
09/11/2008 01:57 PM 0 EMPTY_〜1.TXT empty_testcopy_file.txt
01/21/2008 06:58 PM <DIR> NATION〜1 National Instruments下载
10/12/2007 11:25 AM <DIR> NVIDIA
2008年5月13日09:42 <DIR> Office10
09/19/2008 11:08 AM <DIR> PROGRA〜1程序文件
1999年2月12日下午24:54 24,576 setx.exe
09/15/2008 11:19 AM <DIR> TEMP
02/14/2008 12:26 PM <DIR> tmp
2008年1月21日下午7:05 <DIR> VXIPNP
09/23/2008 12:15 PM <DIR> WINDOWS
02/21/2008 03:49 PM <DIR> wx28
02/29/2008 01:47 PM <DIR> WXWIDG〜2 wxWidgets
3个文件510,704字节20个Dir(s)238,250,901,504字节免费
D:\> REM现在使用\ NUL测试和8.3名称
D:>如果存在d:\ docume〜1 \ NUL echo是
是的
这可行,但是有点愚蠢,因为该点已经暗示我在目录中:
D:\ Documents and Settings>如果存在。\ NUL echo是
这是一个脚本,该脚本使用FOR来构建完全限定的路径,然后将其推送以测试该路径是否为目录。请注意,它如何用于带有空格的路径以及网络路径。
@echo off if [%1]==[] goto usage for /f "delims=" %%i in ("%~1") do set MYPATH="%%~fi" pushd %MYPATH% 2>nul if errorlevel 1 goto notdir goto isdir :notdir echo not a directory goto exit :isdir popd echo is a directory goto exit :usage echo Usage: %0 DIRECTORY_TO_TEST :exit
上面存储为" isdir.bat"的示例输出:
C:\>isdir c:\Windows\system32 is a directory C:\>isdir c:\Windows\system32\wow32.dll not a directory C:\>isdir c:\notadir not a directory C:\>isdir "C:\Documents and Settings" is a directory C:\>isdir \ is a directory C:\>isdir \ninja\SharedDocs\cpu-z is a directory C:\>isdir \ninja\SharedDocs\cpu-z\cpuz.ini not a directory
这有效:
if exist %1\* echo Directory
使用包含空格的目录名称:
C:\>if exist "c:\Program Files\*" echo Directory Directory
请注意,如果目录包含空格,则必须使用引号:
C:\>if exist c:\Program Files\* echo Directory
也可以表示为:
C:\>SET D="C:\Program Files" C:\>if exist %D%\* echo Directory Directory
孩子们,在家可以安全尝试!
使用%%〜si \ NUL
方法的一个问题是,它有可能猜错了。文件名可能会缩短为错误的文件。我不认为%%〜si
可以解析8.3文件名,但可以猜测,但是可以使用字符串操作来缩短文件路径。我相信,如果我们具有类似的文件路径,则可能无法正常工作。
替代方法:
dir /AD %F% 2>&1 | findstr /C:"Not Found">NUL:&&(goto IsFile)||(goto IsDir) :IsFile echo %F% is a file goto done :IsDir echo %F% is a directory goto done :done
我们可以用其他批处理命令替换((goto IsFile)|||(goto IsDir):
(echo是文件)||(echo是目录)`
我用这个:
if not [%1] == [] ( pushd %~dpn1 2> nul if errorlevel == 1 pushd %~dp1 )
最近由于与上述不同的方法而失败。非常确定他们过去曾经工作过,也许与这里的dfs有关。现在使用文件属性并剪切第一个字符
@echo off SETLOCAL ENABLEEXTENSIONS set ATTR=%~a1 set DIRATTR=%ATTR:~0,1% if /I "%DIRATTR%"=="d" echo %1 is a folder :EOF
除了我以前的产品,我发现这也行得通:
if exist %1\ echo Directory
不需要%1左右的引号,因为调用者将提供它们。
这比我一年前的答案节省了整个按键时间;-)