Specifying folders for FileNames
You can simply provide the list of directories as the second argument to FileNames
:
subFolders = {"subfolder", FileNameJoin[{"subfolder", "subsubfolder"}]};
parentFolders = {ParentDirectory[], ParentDirectory[2]}
filesList1 = FileNames["*", subFolders]
filesList2 = FileNames["*", parentFolders]
You can use patterns in the folder path specification:
patternSubFolders = {"Wolfram*", "d" ~~ __};
filesList1 = FileNames["*", patternSubFolders]
{"data\\Untitled-3.nb", "Wolfram Mathematica\\test.nb", "Wolfram\\Video"}
Note that FileNames
and CreateDirectory
also allow specifying the parent directory and the current directory using the ..
and .
syntax respectively (but this functionality is undocumented, so I wouldn't recommend relying on it):
parentFolders = {"..", FileNameJoin[{"..", ".."}]};
They also allow specifying that the path starts from root of the drive by starting the path with either /
or \\
(on Windows):
CreateDirectory["/test1"]
CreateDirectory["\\test2"]
FileNames["/test@"]
"C:\\test1"
"C:\\test2"
{"\\test1", "\\test2"}
More info on abbreviated string patterns
I'm curious if anyone has documentation for abbreviated string patterns (is a comprehensive list shown here?)
This is a link to the Documentation chapter devoted specifically to abbreviated string patterns. They provide very limited functionality and there is only a limited number of (quite old) built-in functions which support them. There are only two metacharacters that are supported by abbreviated string patterns. Here they are along with their escaped forms:
abbreviated string pattern |
meaning |
* |
zero or more characters |
@ |
one or more characters excluding uppercase letters |
\\* |
literal * |
\\@ |
literal @ |
Wrapping a pattern string by Verbatim
disables abbreviated string patterns.
It is not mentioned in the Documentation, but worth knowing that if the function supports abbreviated string patterns, they work also inside of StringExpression
:
StringMatchQ[{"abc", "bcd", "cde"}, StringExpression[("a" | "b"), "*"]]
{True, True, False}
StringCases["abcd", "a*"]
StringCases["abcd", StringExpression[("a" | "b"), "*"]]
{}
{}
StringReplace[{"abc", "bcd", "cde"}, "a*" -> "X"]
{"abc", "bcd", "cde"}
StringReplace[{"abc", "bcd", "cde"}, StringExpression[("a" | "b"), "*"] -> "X"]
{"abc", "bcd", "cde"}
(StringCases
and StringReplace
don't support abbreviated string patterns.)
Also, you should realize that inside of RegularExpression
these metacharacters have an entirely different meaning.
Note also that \\
is used to represent literal backslash , and \"
is used to represent literal double quote " inside of a general String
.
As you can notice from the above, there are some subtleties in interpreting the meaning of \\
in abbreviated string patterns that you need to pay attention to:
With[{sm = HoldForm[StringMatchQ[##]] -> StringMatchQ[##] &}, Style[Column[{sm["@", "\\@"],
sm["@", Verbatim["\\@"]],
sm["\\@", Verbatim["\\@"]],
sm["\\@", "\\@"],
sm["\\@", "\\\\@"]}], "Input", ShowStringCharacters -> True]]

FileNameJoin
is not supposed to be used with patterns
My understanding is that FileNameJoin
must output a string as its result, and StringExpression
and RegularExpression
are just not strings. I think that the "*"
character works because it is a "abbreviated string pattern" as mentioned in the documentation for FileNames
, but I can't find further documentation of what other characters might be usable for abbreviated string patterns.
Actually, your use of FileNameJoin
for composing an abbreviated string pattern is a kind of a hack because FileNameJoin
is not designed to work with patterns.
Perhaps a better solution would be to select all folders with "*"
, then use StringCases
to pick all structures that match the desired pattern.
Yes, some experiments of mine show that this way is the most reliable when working with FileNames
, see:
You can first split the file name with FileNameSplit
, then apply Cases
with Condition
(/;
) containing StringMatchQ
, or use SringCases
with StringExpression
to select the paths you are interested in.