如何测试文件是批处理脚本中的目录?
有什么方法可以找出一个文件是否是一个目录?如何测试文件是批处理脚本中的目录?
我在变量中有文件名。在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
。
(注 - 。上面给出的例子是在一个批处理文件工作的格式要得到它的命令行上工作,在这两个地方%
更换%%
)基于this article题为
“一个批处理文件如何测试一个目录“它”的存在并不完全可靠“。
,但我只是测试了这一点:
@echo off
IF EXIST %1\NUL goto print
ECHO not dir
pause
exit
:print
ECHO It's a directory
pause
,它似乎工作
阅读文章“不可靠”意味着它在Pathworks,Novell,DR-DOS和OS/2上失败,我怀疑这对大多数人来说是一个问题。 – 2008-09-26 12:46:35
因此“不完全可靠” – 2008-09-26 12:54:08
**这不符合** [目录符号链接(Softlinks)或连接](http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html):其路径包含目录链接被误认为目录。要重现,请输入:
的NUL技术似乎只在8.3兼容的文件名的工作。
(换句话说,'d:\ Documents和Settings`是 “坏” 和'd:\ DOCUME〜1`是 “好”)
我认为这是使用一些困难“NUL”tecnique当目录名称中有SPACES时,如“Documents and Settings”。
我使用Windows XP Service Pack 2和启动从的%SystemRoot CMD提示符%\ SYSTEM32 \ cmd.exe的
这里有什么不工作的一些例子,这是什么工作对我来说:
(这些都是演示在交互式提示符下“实时”完成的,我想你应该先在那里工作,然后再尝试在脚本中调试它们。)
这并不工作:
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
下面是一个用来建立一个完全合格的路径的脚本,然后PUSHD到测试路径是否是目录。注意它如何适用于具有空格的路径以及网络路径。
@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
请注意,引号是ne cessary如果该目录包含空格:
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 Is a File)||(echo is a Directory)
我用这个:
if not [%1] == [] (
pushd %~dpn1 2> nul
if errorlevel == 1 pushd %~dp1
)
日前未能与上述不同的方法。相当肯定他们过去工作过,也许在这里与dfs有关。现在使用files attributes切第一个字符
@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号引号,因为主叫方将提供给他们。 这节省了一年前我的答案一个完整的击键;-)
在Windows 7和XP下,我无法让它告诉文件与映射驱动器上的目录。下面的脚本:
@echo off if exist c:\temp\data.csv echo data.csv is a file if exist c:\temp\data.csv\ echo data.csv is a directory if exist c:\temp\data.csv\nul echo data.csv is a directory if exist k:\temp\nonexistent.txt echo nonexistent.txt is a file if exist k:\temp\something.txt echo something.txt is a file if exist k:\temp\something.txt\ echo something.txt is a directory if exist k:\temp\something.txt\nul echo something.txt is a directory
生产:
data.csv is a file something.txt is a file something.txt is a directory something.txt is a directory
所以要小心,如果你的脚本可以喂映射或UNC路径。下面推动的解决方案似乎是最简单的。
这工作完全
if exist "%~1\" echo Directory
我们需要使用%〜1%1除去报价,并在结尾处添加一个反斜杠。然后再把这个整体放入分组中。
这是我在我的批处理文件
```
@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
```
一个非常简单的方法是检查是否存在儿童使用的代码。
如果孩子没有任何孩子,exist
命令将返回false。
IF EXIST %1\. (
echo %1 is a folder
) else (
echo %1 is a file
)
如果您没有足够的访问权限(我没有测试过),您可能会有一些错误的否定。
我们不能只用这个测试:
IF [%~x1] == [] ECHO Directory
这似乎为我工作。
这里是我的解决方案:
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
好......如果您在名称中使用引号的“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
,或者如果你可以向你保证满足所有的“NUL”解决方案的需求是:
if exist %~sf1\nul echo Directory
把这些放入像'test.bat'这样的批处理文件中并执行'test.bat MyFile'。
这里是经过多次试验我的解决方案与是否存在,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
- 它与UNC路径一起使用
- 它可以使用双引号完整路径或仅使用dirname或文件名。
- 即使您没有读取权限,它也能正常工作
- 它适用于目录链接(连接点)。
- 它适用于路径中包含目录链接的文件。
这个工程还负责在他们的空间的路径:
dir "%DIR%" > NUL 2>&1
if not errorlevel 1 (
echo Directory exists.
) else (
echo Directory does not exist.
)
可能不是最有效的,但更容易比在我看来,其他的解决方案阅读。
@ batchman61方法的变体(检查目录属性)。
这次我使用外部'find'命令。
(哦,并注意&&
诀窍这是为了避免长时间枯燥的语法IF ERRORLEVEL
)上
@ECHO OFF
SETLOCAL EnableExtentions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
输出有:
- 目录。
- 目录符号链接或路口。
- 残破目录符号链接或路口。 (不设法解决的链接。)
- 目录,你对(如“C:\的System Volume Information”)没有读取权限
如果你能cd
到它,这是一个目录:
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%
我想发布我自己的关于这个主题的函数脚本希望对某人有用一天。
@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:存在,它是一个文件。
你忘了d旗我认为 – 2008-09-26 12:05:41
这是行不通的。 – Vhaerun 2008-09-26 12:17:27
它适用于我和什么“D”标志?罗马语 - 答案中的“D:”是机器上“D:”驱动器的参考。 Vhaerun - 当你尝试这个时,你有什么VAR设置? – 2008-09-26 13:04:32