如何testing文件是批处理脚本中的目录?
有没有办法找出一个文件是否是一个目录?
我有一个variables的文件名。 在Perl中,我可以这样做:
if(-d $var) { print "it's a directory\n" }
你可以这样做:
IF EXIST %VAR%\NUL ECHO It's a directory
但是,这只适用于名称中没有空格的目录。 当您将引号添加到variables处理空格时,它将停止工作。 要处理带空格的目录,请按如下所示将文件名转换为简短的8.3格式:
FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory
%%~si
将%%i
转换为8.3文件名。 要查看可以使用FOR
variables执行的所有其他技巧,请在命令提示符处inputHELP FOR
。
(注意 – 上面给出的例子的格式是在batch file中工作,为了使它在命令行上工作,在两个地方用%
replace%%
。)
这工作:
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
这是安全的在家里试试,孩子们!
最近以不同的方法从上面失败。 相当肯定他们在过去工作,也许在这里与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周围的引号。 这节省了我一年前的答案一个完整的击键;-)
这是一个使用FOR构build完全限定path的脚本,然后pushd来testingpath是否是一个目录。 注意它是如何工作的path与空间,以及networkingpath。
@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
我们需要使用%〜1从%1中删除引号,并在末尾添加一个反斜杠。 然后把整个重新组合成queta。
NUL技术似乎只适用于8.3兼容的文件名。
(换句话说,`D:\ Documents and Settings`是“坏”,而`D:\ DOCUME〜1`是“好”)
如果在目录名称中有SPACES,比如“Documents and Settings”,那么使用“NUL”技术会有一些困难。
我正在使用Windows XP Service Pack 2并从%SystemRoot%\ system32 \ cmd.exe启动cmd提示符
以下是DID不能工作的一些例子,以及对我来说有什么作用:
(这些都是演示在交互式提示符下“实时”完成的,我想你应该先在那里工作,然后才能在脚本中debugging它们。)
这不是工作:
D:\Documents and Settings>if exist "D:\Documents and Settings\NUL" echo yes
这不是工作:
D:\Documents and Settings>if exist D:\Documents and Settings\NUL echo yes
这是否工作(对我来说):
D:\Documents and Settings>cd ..
D:\>REM get the short 8.3 name for the file
D:\>dir /x
Volume in drive D has no label.
Volume Serial Number is 34BE-F9C9
Directory of D:\
09/25/2008 05:09 PM <DIR> 2008
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
[[看看这里! ]]
09/25/2008 08:34 AM <DIR> DOCUME~1 Documents and Settings
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 Downloads
10/12/2007 11:25 AM <DIR> NVIDIA
05/13/2008 09:42 AM <DIR> Office10
09/19/2008 11:08 AM <DIR> PROGRA~1 Program Files
12/02/1999 02:54 PM 24,576 setx.exe
09/15/2008 11:19 AM <DIR> TEMP
02/14/2008 12:26 PM <DIR> tmp
01/21/2008 07:05 PM <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 File(s) 510,704 bytes
20 Dir(s) 238,250,901,504 bytes free
D:\>REM now use the \NUL test with the 8.3 name
D:\>if exist d:\docume~1\NUL echo yes
yes
这工作,但它是一种愚蠢的,因为点已经暗示我在一个目录中:
D:\Documents and Settings>if exist .\NUL echo yes
这工作,也处理与他们的空间的path:
dir "%DIR%" > NUL 2>&1 if not errorlevel 1 ( echo Directory exists. ) else ( echo Directory does not exist. )
在我看来,这可能不是最有效但比其他解决scheme更容易阅读的。
@ batchman61方法的变体(检查目录属性)。
这次我使用外部的“查找”命令。
(哦,并注意&&
技巧,这是为了避免冗长的IF ERRORLEVEL
语法。)
@ECHO OFF SETLOCAL EnableExtentions ECHO.%~a1 | find "d" >NUL 2>NUL && ( ECHO %1 is a directory )
输出是:
- 目录。
- 目录符号链接或路口。
- 破碎的目录符号链接或路口。 (不尝试parsing链接。)
- 您没有读取权限的目录(例如“C:\ System Volume Information”)
我使用这个:
if not [%1] == [] ( pushd %~dpn1 2> nul if errorlevel == 1 pushd %~dp1 )
一个非常简单的方法是检查孩子是否存在。
如果一个孩子没有任何孩子,则exist
命令将返回false。
IF EXIST %1\. ( echo %1 is a folder ) else ( echo %1 is a file )
如果您没有足够的访问权限(我没有testing过),您可能会有一些错误的否定。
根据这篇题为“如何batch filetesting目录的存在” 这篇文章 “不完全可靠”。
但我只是testing了这一点:
@echo off IF EXIST %1\NUL goto print ECHO not dir pause exit :print ECHO It's a directory pause
它似乎工作
这是我的解决scheme:
REM make sure ERRORLEVEL is 0 TYPE NUL REM try to PUSHD into the path (store current dir and switch to another one) PUSHD "insert path here..." >NUL 2>&1 REM if ERRORLEVEL is still 0, it's most definitely a directory IF %ERRORLEVEL% EQU 0 command... REM if needed/wanted, go back to previous directory POPD
如果你可以进入它,它是一个目录:
set cwd=%cd% cd /D "%1" 2> nul @IF %errorlevel%==0 GOTO end cd /D "%~dp1" @echo This is a file. @goto end2 :end @echo This is a directory :end2 @REM restore prior directory @cd %cwd%
在Windows 7和XP下,我无法让它告诉文件与映射驱动器上的目录。 以下脚本:
@echoclosures 如果存在c:\ temp \ data.csv echo data.csv是一个文件 如果存在c:\ temp \ data.csv \ echo data.csv是一个目录 如果存在c:\ temp \ data.csv \ nul echo data.csv是一个目录 如果存在k:\ temp \ nonexistent.txt echo nonexistent.txt是一个文件 如果存在k:\ temp \ something.txt echo something.txt是一个文件 如果存在k:\ temp \ something.txt \ echo something.txt是一个目录 如果存在k:\ temp \ something.txt \ nul echo something.txt是一个目录
生产:
data.csv是一个文件 something.txt是一个文件 something.txt是一个目录 something.txt是一个目录
所以要小心,如果您的脚本可能会被映射或UNCpath。 下面推动的解决scheme似乎是最简单的。
这是我在我的BATCH文件中使用的代码
``` @echo off set param=%~1 set tempfile=__temp__.txt dir /b/ad > %tempfile% set isfolder=false for /f "delims=" %%i in (temp.txt) do if /i "%%i"=="%param%" set isfolder=true del %tempfile% echo %isfolder% if %isfolder%==true echo %param% is a directory
“`
好的…如果你在名称中使用引号,那么这个'nul'技巧是行不通的,这个引号占了大多数长文件名或空格的文件。
例如,
if exist "C:\nul" echo Directory
什么都不做,但是
if exist C:\nul echo Directory
作品。
我终于想出了这个,似乎适用于所有情况:
for /f %%i in ('DIR /A:D /B %~dp1 ^| findstr /X /c:"%~nx1"') do echo Directory
或者如果你能确保你满足所有“不”的要求,一个解决scheme是:
if exist %~sf1\nul echo Directory
把这些放到batch file中,比如'test.bat',然后做'test.bat MyFile'。
这是我的解决scheme经过多次testing,如果存在,pushd,dir / AD等…
@echo off cd /d C:\ for /f "delims=" %%I in ('dir /a /ogn /b') do ( call :isdir "%%I" if errorlevel 1 (echo F: %%~fI) else echo D: %%~fI ) cmd/k :isdir echo.%~a1 | findstr /b "d" >nul exit /b %errorlevel% :: Errorlevel :: 0 = folder :: 1 = file or item not found
- 它适用于没有扩展名的文件
- 它适用于名为folder.ext的文件夹
- 它适用于UNCpath
- 它使用双引号完整path或者只使用dirname或filename。
- 即使您没有读取权限,它也能正常工作
- 它与目录链接(连接)。
- 它适用于其path包含目录链接的文件。
使用%%~si\NUL
方法的一个问题是有可能猜测错误。 它可能有一个文件名缩短到错误的文件。 我不认为%%~si
parsing8.3文件名,但猜测它,但使用string操作来缩短文件path。 我相信如果你有类似的文件path可能无法正常工作。
另一种方法:
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
您可以用其他批处理命令replace(goto IsFile)||(goto IsDir)
:
(echo Is a File)||(echo is a Directory)
我想发布我自己的关于这个主题的函数脚本,希望有一天对别人有用。
@pushd %~dp1 @if not exist "%~nx1" ( popd exit /b 0 ) else ( if exist "%~nx1\*" ( popd exit /b 1 ) else ( popd exit /b 3 ) )
这个批处理脚本检查文件/文件夹是否存在,以及它是否是文件或文件夹。
用法:
script.bat“PATH”
退出代码:
0:文件/文件夹不存在。
1:存在,它是一个文件夹。
3:存在,它是一个文件。
我们不能只用这个testing:
IF [%~x1] == [] ECHO Directory
这似乎为我工作。