# List all the directories under the current one

I feel like I am forgetting something obvious, and will remember or be ashamed as soon as an answer turns up. However, I cannot for the life of me get all of the directories in the current working directory. That is, given the following folder structure:

a
-c
b
-c


I would expect

FileNames["*",{"*"},Infinity]


to return

{"a","b","a/c","b/c"}


{"a/c","b/c"}


I tried playing around with Infinity in the typical Levels in Mathematica (such as {1} vs. 1), but MMA complains about syntax. For the above example, how can I view a complete list of subdirectories. I came up with the following, but it doesn't seem exactly elegant:

RecursiveDirectory[dir_] :=
Module[{allDirs, allDirsCheck = {}, tempDirs},
allDirs = Select[FileNames["*"], DirectoryQ[#] &];
While[allDirs != allDirsCheck,
allDirsCheck = allDirs;
tempDirs = Select[FileNames["*", allDirs], DirectoryQ[#] &];
allDirs = Union[allDirs, tempDirs]
];
allDirs
]


This function gives me:

In[30]:= RecursiveDirectory["*"]
Out[30]= {"a", "a\\c", "b", "b\\c"}


As expected. What is a nicer way of doing this?

-

Maybe something like

Select[FileNames["*", "", Infinity], DirectoryQ]

-
Thanks Heike, I didn't think of trying an empty quote. I think I tried everything but that. And I knew the answer would be very simple too.... –  tkott Feb 27 '12 at 21:05

If I'm not mistaken the second asterisk in your line

FileNames["*",{"*"},Infinity]


should be replaced with the location of the directory you want to look in.

In case of the directory where your notebook lives in this would be:

FileNames["*", {NotebookDirectory[]}, Infinity]


or, for the current directory, this would be:

FileNames["*", {Directory[]}, Infinity]

-
Thanks Sjoerd. +1 for a detailed answer, but according to MMA.SE, Heike answered first (post 2389 vs. 2390) –  tkott Feb 27 '12 at 21:06
@tkott This isn't a racing contest and please don't feel obliged to accept an answer the minute it arrives. That will discourage others to add their answers. –  Sjoerd C. de Vries Feb 27 '12 at 21:24

I recommend an external command approach. On Windows this looks like this:

command = "!dir \"" <> Directory[] <> "\" /A:D /S /B";



This can be many times faster than the Select - FileNames method.

Select[
FileNames["*", "C:\\Data & Images", Infinity],
DirectoryQ
] // Length // AbsoluteTiming

{6.7413856, 5693}

command = "!dir \"" <> "C:\\Data & Images" <> "\" /A:D /S /B";
ReadList[command, String] // Length // AbsoluteTiming

{0.3900223, 5693}

-
I use ReadList often but had never discovered this. Good stuff! +1 –  Andy Ross Feb 28 '12 at 6:26
@Andy thank you. I presume you mean the ability to read command line output? –  Mr.Wizard Feb 28 '12 at 20:21
Yes, that is what I was referring to. I had a vague idea about using command line input in other places, I didn't realize it worked here as well. Potentially a very powerful idea. –  Andy Ross Feb 28 '12 at 20:25
@Andy yes, it's surely cleaner than having to write to a temporary file, only to ReadList that. I think this should be better documented (present on the ReadList doc page). –  Mr.Wizard Feb 28 '12 at 20:30
You should file that as a suggestion to WRI if you haven't already. –  Andy Ross Feb 28 '12 at 20:35