views:

2865

answers:

9

Is there any way to say if a file is a directory? I have the filename in a variable. In Perl I can do this:

if(-d $var) { print "it's a directory\n" }

+3  A: 

You can do it like so:

IF EXIST %VAR%\NUL ECHO It's a directory

However, this only works for directories without spaces in their names. When you add quotes round the variable to handle the spaces it will stop working. To handle directories with spaces, convert the filename to short 8.3 format as follows:

FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory

The %%~si converts %%i to an 8.3 filename. To see all the other tricks you can perform with FOR variables enter HELP FOR at a command prompt.

(Note - the example given above is in the format to work in a batch file. To get it work on the command line swap both the %% for %.)

Dave Webb
you forgot the d flag i think
Roman M
This doesn't work .
Vhaerun
It worked fine for me and what "D" flag? Roman - The "D:" in your answer is a reference the "D:" drive on your machine. Vhaerun - what did you have VAR set to when you tried this?
Dave Webb
Nice tip with the ~s for "short names." Thanks for adding that. +1 helpful.
que que
+1  A: 

Based on this titled "How can a batch file test existence of a directory" its "not entirely reliable".

BUT i just tested this:

@echo off
IF EXIST d:%1\NUL goto print
ECHO not dir
pause
exit
:print
ECHO It's a directory
pause

and it seems to work

Roman M
Reading the article "unreliable" means that it failed on Pathworks, Novell, DR-DOS and OS/2 which I doubt will be a problem for most people.
Dave Webb
hence "not entirely reliable"
Roman M
+4  A: 
que que
The problem appears to be not with long file names but directories with spaces in their names. Or rather, it's the quotes around the variable name that stop the NUL trick from working. I've added some code to my answer which converts file names to 8.3 names before testing.
Dave Webb
+2  A: 

Here's a script that uses FOR to build a fully qualified path, and then pushd to test whether the path is a directory. Notice how it works for paths with spaces, as well as network paths.

@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

Sample output with the above saved as "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
indiv
A: 

This seems to work:

if exist %1\* echo Directory

Seems too easy, and there's a niggle at the back of my brain that says not to do it. Anyone know why not?

Gerard
It will fail for directories with spaces in their name unless you put quotes around the argument.
Joey
No it doesn't. %1 will already be quoted. Try it.
Gerard
A: 

One issue with using %%~si\NUL method is that there is the chance that it guesses wrong. Its possible to have a filename shorten to the wrong file. I don't think %%~si resolves the 8.3 filename, but guesses it, but using string manipulation to shorten the filepath. I believe if you have simuliar file paths it may not work.

An alternative method:

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

You can replace (goto IsFile)||(goto IsDir) with other batch commands: (echo Is a File)||(echo is a Directory)

TechGuy
A: 

I use this:

if not [%1] == [] (
  pushd %~dpn1 2> nul
  if errorlevel == 1 pushd %~dp1
)
Kimae
A: 

recently failed with different approaches from the above, quite sure they worked in the past, maybe related to dfs here. now using the files attributes and cut first char

@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF
batchman61
A: 

Further to my previous offering, I find this also works:

if exist %1\ echo Directory

No quotes around %1 are needed because the caller will supply them. This saves one entire keystroke over my answer of a year ago ;-)

Gerard