如何在批处理脚本中测试文件是否为目录?

时间:2020-03-06 14:46:45  来源:igfitidea点击:

有没有办法找出文件是否是目录?

我在变量中有文件名。在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 &lt;DIR> 200809〜1.25 2008.09.25
09/23/2008 03:44 PM &lt;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 &lt;DIR> cygwin

看这里!!!!
2008-09-25 08:34 &lt;DIR> DOCUME〜1文档和设置

09/11/2008 01:57 PM 0 EMPTY_〜1.TXT empty_testcopy_file.txt
01/21/2008 06:58 PM &lt;DIR> NATION〜1 National Instruments下载
10/12/2007 11:25 AM &lt;DIR> NVIDIA
2008年5月13日09:42 &lt;DIR> Office10
09/19/2008 11:08 AM &lt;DIR> PROGRA〜1程序文件
1999年2月12日下午24:54 24,576 setx.exe
09/15/2008 11:19 AM &lt;DIR> TEMP
02/14/2008 12:26 PM &lt;DIR> tmp
2008年1月21日下午7:05 &lt;DIR> VXIPNP
09/23/2008 12:15 PM &lt;DIR> WINDOWS
02/21/2008 03:49 PM &lt;DIR> wx28
02/29/2008 01:47 PM &lt;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左右的引号,因为调用者将提供它们。
这比我一年前的答案节省了整个按键时间;-)