Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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"}

But instead I get

{"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?

share|improve this question
add comment

3 Answers

up vote 21 down vote accepted

Maybe something like

Select[FileNames["*", "", Infinity], DirectoryQ]
share|improve this answer
1  
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
add comment

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]
share|improve this answer
    
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
7  
@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
add comment

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

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

ReadList[command, String]

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}
share|improve this answer
    
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
1  
@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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.