How to differentiate directory vs file in loop

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
mskavim
Posts: 9
Joined: 25 Jan 2015 14:51

How to differentiate directory vs file in loop

#1 Post by mskavim » 26 Jan 2015 12:31

I am looping the content of a directory which has files and sub-directory. so I want to find out if it is a file or a directory. I don't want hard code name of the file or directory name in the script.


Code: Select all

FOR /f "tokens=*" %%D IN ('DIR /B /AD /ON') DO (
    ECHO #---"%%D"---#
    CD "%%D"
   FOR /f "tokens=*" %%F IN ('DIR /B *') DO (
      IF /I "%%D"=="Preferences" (
         REM ECHO Importing file "%%F"...
         
         REM WHAT to find out if %%F is director to file..
      )
   )
    CD ..
)
ECH



Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: How to differentiate directory vs file in loop

#3 Post by Squashman » 26 Jan 2015 12:45

%%~aF will expand to d-------- if it is a folder.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: How to differentiate directory vs file in loop

#4 Post by dbenham » 26 Jan 2015 12:54

@Squashman: A folder may have other attributes set, such as ReadOnly or Archive. So the string may not be "d--------"

The simplest test is to append \ and test if it exists:

Code: Select all

if exist "%%F\" (echo %%F is a folder) else (echo %%F is a file)


Dave Benham

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: How to differentiate directory vs file in loop

#5 Post by Liviu » 26 Jan 2015 13:14

dbenham wrote:A folder may have other attributes set, such as ReadOnly or Archive. So the string may not be "d--------"

Code: Select all

C:\temp>for %v in ("%cd%") do @if "%~av" geq "d" (echo it's a directory) else if "%~av" geq "-" (echo it's a file) else (echo no such path)
it's a directory

Liviu

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: How to differentiate directory vs file in loop

#6 Post by dbenham » 26 Jan 2015 13:34

Liviu wrote:

Code: Select all

C:\temp>for %v in ("%cd%") do @if "%~av" geq "d" (echo it's a directory) else if "%~av" geq "-" (echo it's a file) else (echo no such path)
it's a directory

Liviu

Ooh, I don't think I've seen that simple solution before. I like it :D


Dave Benham

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: How to differentiate directory vs file in loop

#7 Post by Squashman » 26 Jan 2015 14:07

Yes I probably worded the incorrectly. Easy enough to substring or echo to findstr to get an errolevel.

Code: Select all

H:\>@for %v in ("testfile.txt") do @for /f "delims=d" %G in ("%~av") do @if NOT "%~G"=="%~av" (echo it's a directory) else  (echo it's a file)
it's a file

H:\>@for %v in ("%cd%") do @for /f "delims=d" %G in ("%~av") do @if NOT "%~G"=="%~av" (echo it's a directory) else  (echo it's a file)
it's a directory

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: How to differentiate directory vs file in loop

#8 Post by dbenham » 26 Jan 2015 14:50

Yes, that is how I thought to check. But FIND/FINDSTR is innefficient and substring requires an extra variable plus delayed expansion, which may not be safe without toggling.

But Liviu's inequality comparison is very simple and efficient, and I can't envision a scenario where it could fail.

mskavim
Posts: 9
Joined: 25 Jan 2015 14:51

Re: How to differentiate directory vs file in loop

#9 Post by mskavim » 26 Jan 2015 16:00

This worked IF "%%~aP" GEQ "d" ... I was getting sysntax error for ) when I use IF EXIST "%%P\"

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: How to differentiate directory vs file in loop

#10 Post by Squashman » 26 Jan 2015 17:14

mskavim wrote:This worked IF "%%~aP" GEQ "d" ... I was getting sysntax error for ) when I use IF EXIST "%%P\"

??
Without seeing all your code and how you tried to use it we will never be able to tell you what you did wrong.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: How to differentiate directory vs file in loop

#11 Post by Aacini » 26 Jan 2015 20:30

Perhaps a dumb question: Why is necessary to identify in the list of elements produced by DIR command the ones that are files and the ones that are directories?

Code: Select all

for /F "delims=" %%a in ('dir /B') do (
   if "%%a" is file (
      process %%a as file
   ) else (
      process %%a as directory
   )
)

You may just process each type with the proper FOR command:

Code: Select all

for %%a in (*.*) do (
   process file %%a
)
for /D %%a in (*) do (
   process directory %%a
)

This code is simpler, clearer and run faster than the previous one. If both methods would be executed in all subdirectories of a large tree, the difference in run time between they may be notorious.

Of course, FOR /F ... in ('DIR...') may be very useful in certain cases, but lately I have seen a series of examples that may be solved directly via plain FOR or FOR /D commands, but the OPs get in trouble when they wants to use a FOR /F instead...

Antonio

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: How to differentiate directory vs file in loop

#12 Post by dbenham » 26 Jan 2015 20:54

If the user did only want to process one type, then FOR /F could still be used: DIR /B /A-D for files, and DIR /B /AD for folders.

Presumably the OP wants to process both in one loop, but it is not clear.

Even if only one type is needed, FOR /F with DIR /B is required if the directory listing will change during the course of the loop because the simple FOR can be affected by the midstream changes.

But, I agree that many people get in the habit of using FOR /F when it is not needed.


Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: How to differentiate directory vs file in loop

#13 Post by foxidrive » 29 Jan 2015 07:47

dbenham wrote:The simplest test is to append \ and test if it exists:

Code: Select all

if exist "%%F\" (echo %%F is a folder) else (echo %%F is a file)



It's fine for a local drive but this will fail on a network drive IIRC.

rojo
Posts: 26
Joined: 14 Jan 2015 13:51

Re: How to differentiate directory vs file in loop

#14 Post by rojo » 29 Jan 2015 08:11

foxidrive wrote:
dbenham wrote:The simplest test is to append \ and test if it exists:

Code: Select all

if exist "%%F\" (echo %%F is a folder) else (echo %%F is a file)



It's fine for a local drive but this will fail on a network drive IIRC.


After testing, it appears that it doesn't fail on a network drive; but it succeeds where it should fail.

Code: Select all

S:\OIT>if exist wwwlogs\ echo is a folder
is a folder

S:\OIT>if exist your-signed-update.zip\ echo is a folder
is a folder


I think a better test would be

Code: Select all

if exist "%%F\NUL" (echo %%F is a folder) else (echo %%F is a file)


Example:

Code: Select all

S:\OIT>if exist "your-signed-update.zip\NUL" echo is a folder

S:\OIT>if exist wwwlogs\NUL echo is a folder
is a folder

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: How to differentiate directory vs file in loop

#15 Post by foxidrive » 29 Jan 2015 08:44

rojo wrote:it succeeds where it should fail.


This is the usual definition of a failure. :D

Locked