Windows Batch File Looping Through Directories to Process Files?

104,508

Solution 1

You may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:

@echo off
call :treeProcess
goto :eof

:treeProcess
rem Do whatever you want here over the files of this subdir, for example:
for %%f in (*.tif) do echo %%f
for /D %%d in (*) do (
    cd %%d
    call :treeProcess
    cd ..
)
exit /b

Solution 2

Aacini's solution works but you can do it in one line:

for /R %%f in (*.tif) do echo "%%f"

Solution 3

Jack's solution work best for me but I need to do it for network UNC path (cifs/smb share) so a slight modification is needed:

for /R "\\mysrv\imgshr\somedir" %%f in (*.tif) do echo "%%f"

The original tip for this method is here

Solution 4

Posting here as it seems to be the most popular question about this case.

Here is an old gem I have finally managed to find back on the internet: sweep.exe.
It executes the provided command in current directory and all subdirectories, simple as that.


Let's assume you have some program that process all files in a directory (but the use cases are really much broader than this):

:: For example, a file C:\Commands\processimages.cmd which contains:
FOR %%f IN (*.png) DO whatever

So, you want to run this program in current directory and all subdirectories:

:: Put sweep.exe in your PATH, you'll love it!
C:\ImagesDir> sweep C:\Commands\processimages.cmd

:: And if processimages.cmd is in your PATH too, the command becomes:
C:\ImagesDir> sweep processimages


Pros: You don't have to alter your original program to make it process subdirectories. You have the choice to process the subdirectories only if you want so. And this command is so straightforward and pleasant to use.

Con: Might fail with some commands (containing spaces, quotes, I don't know). See this thread for example.

Solution 5

I know this is not recursion (iteration through enumerated subdirectories?), but it may work better for some applications:

for /F "delims=" %%i in ('dir /ad /on /b /s') do (
    pushd %%i
    dir | find /i "Directory of"
    popd
)

Replace the 3rd line with whatever command you may need.

dir /ad - list only directories

The cool thing is pushd does not need quotes if spaces in path.

Share:
104,508
Tyler
Author by

Tyler

Systems Administrator and PHP Programmer

Updated on July 18, 2022

Comments

  • Tyler
    Tyler almost 2 years

    I need to write/use a batch file that processes some imagery for me.

    I have one folder full of nested folders, inside each of these nested folders is one more folder that contains a number of TIF images, the number of images vary in each folder. I also have a batch file, lets call it ProcessImages.bat for Windows that you can "drop" these TIF files on (or obviously specify them in a command line list when invoking the bat); upon which it creates a new folder with all my images process based on an EXE that I have.

    The good thing is that because the bat file uses the path from the folders you "drop" onto it, I can select all the TIFs of one folder and drop it to do the processing... but as I continue to manually do this for the 300 or so folders of TIFs I have I find it bogs my system down so unbelievably and if I could only process these one at a time (without manually doing it) it would be wonderful.

    All that said... could someone point me in the right direction (for a Windows bat file AMATEUR) in a way I can write a Windows bat script that I can call from inside a directory and have it traverse through ALL the directories contained inside that directory... and run my processing batch file on each set of images one at a time?

  • Dexters
    Dexters over 11 years
    @Aacini . Can you also explai/comment what these /D, %%f commands do? That would be great !
  • Sachini Samarasinghe
    Sachini Samarasinghe over 10 years
    you can find more on syntax from the following url. microsoft.com/resources/documentation/windows/xp/all/proddoc‌​s/…
  • Elias ringhauge
    Elias ringhauge about 9 years
    Really great, you saved my day. Used %CD%%%f for absolute path+file as argument to a program.
  • Tyler
    Tyler about 8 years
    Don't know how many years later, but I'm still using this one!
  • Eliezer Miron
    Eliezer Miron almost 8 years
    I'm using this, and for some reason, it does the command for every file in the directory tree, not just the ones with the extension I specify
  • Aacini
    Aacini over 7 years
    As I said, my method gives exact control of what you do in every subdirectory. If the process would require a certain order (for example, first move files and then delete empty subdirectories) it just can not be achieved using for /R...
  • Tyler
    Tyler almost 6 years
    I consistently come back to this answer whenever I have to do a similar batch file looping. Really helpful even years later.
  • thehelix
    thehelix almost 6 years
    Really great solution for the quick 'n dirty job I need to get done ASAP.
  • Robert Pollak
    Robert Pollak over 5 years
    I think the lines "call :treeProcess" and "goto :eof" can be omitted.
  • Aacini
    Aacini over 5 years
    @RobertPollak: You are right! :) In such a case, the last exit /B may also be omitted...
  • Robert Pollak
    Robert Pollak over 5 years
    This does not work if you need the "current directory" to be set at each subdirectory.
  • user2010136
    user2010136 over 5 years
    Aacini's works for one directory, this works for all directories from your starting point. This is what i was looking for! Thanks!
  • akinuri
    akinuri about 4 years
    Can't I use a variable after the /R? I'm passing (drag-drop) files/folder to the batch file and have a main loop (FOR %%i IN (%*) DO) that checks if the argument is a dir or file.If the argument is a dir, I have a second loop and that loop needs to be recursive. I couldn't make it work using a varible from the main loop: FOR /R %%i %%f IN (*) DO. I've tried different combinations, but /R %%i just doesn't work.
  • Jakob Sternberg
    Jakob Sternberg over 2 years
    @akinuri Try make a batfile with this for /R %1 %%f in (*.txt) do echo "%%f" and drag drop a folder onto it.
  • PJP
    PJP over 2 years
    See "Explaining entirely code-based answers". While this might be technically correct it doesn't explain why it solves the problem or should be the selected answer. We should educate in addition to help solve the problem.
  • Jeremy Caney
    Jeremy Caney over 2 years
    There are five existing answers to this question, including a top-voted, accepted answer with over one hundred votes. Are you certain your solution hasn't already been given? If not, why do you believe your approach improves upon the existing proposals, which have been validated by the community? Offering an explanation is always useful on Stack Overflow, but it's especially important where the question has been resolved to the satisfaction of both the OP and the community. Help readers out by explaining what your answer does different and when it might be preferred.