File Exchange

image thumbnail

subdir: a recursive file search

version 1.1.0.0 (3.87 KB) by Kelly Kearney
Performs a recursive file search using same input and output format as dir function

24 Downloads

Updated 16 Aug 2016

From GitHub

View Version History

View license on GitHub

This function performs a recursive file search. Its advantage over other FEX programs offering the same thing is that it uses the same input and output format as Matlab's dir function, and can therefore be used interchangeably.
Example:

>> a = subdir(fullfile(matlabroot, 'toolbox', 'matlab', '*.mat'))

a =

66x1 struct array with fields:
name
date
bytes
isdir
datenum

>> a(1)

ans =

name: '/Applications/MATLAB74/toolbox/matlab/audiovideo/chirp.mat'
date: '14-Mar-2004 10:31:48'
bytes: 25276
isdir: 0
datenum: 7.3202e+05

Cite As

Kelly Kearney (2021). subdir: a recursive file search (https://github.com/kakearney/subdir-pkg), GitHub. Retrieved .

Comments and Ratings (19)

Nicolai Jørgensen

Works brilliant!

Kelly Kearney

@Sanket Unhale, The dir function gained the ability to search subdirectories as of R2016b, at which point it also started returning the parent folder of each file it listed. Prior to that, it didn't return the folder, and didn't search recursively. So for newer releases, you're probably better off just using dir; this function fills the gap for earlier releases.

Sanket Unhale

Great release. The only thing that I modified in your function is to keep the Files.name as only file name, and not return the full path, which exactly matches the output of "dir" function. It felt redundant that it returned full path of each file under Files.name and also returned the folder names.

Joseph Slaton

Kelly, there is a bug when you have a folder with a semicolon in the name, which is legal in Windows filesystems. Since this is also the 'pathsep' in windows systems, it splits incorrectly the pathstr. My fix was changing line 88 to:
pathfolders = regexp(pathstr, [pathsep pathsep], 'split');

and lines 146 to 152 to be:

for i=1:length(dirs)
dirname = dirs(i).name;
if ~strcmp( dirname,'.') && ~strcmp( dirname,'..')
p = [p pathsep genpath(fullfile(d,dirname))]; % Recursive calling of this function.
end
end
p = [p pathsep];

Kelly Kearney

@Luca,

Thanks for pointing that out; seems I accidentally introduced that bug when merging the ./..-pruning code. Now fixed.

Luca

It throws an error when choosing a folder with the wrong extension:
"Struct contents reference from a non-struct array object.
Error in subdir (line 103)
[~, ~, tail] = cellfun(@fileparts, {Files(:).name}, 'UniformOutput', false);"

es

Thank you, works perfectly and you taught us all something new!

Sebastian Endrikat

bilalY

kuni

Paul

Great! Does as it claims.

Sanjay

Works really well. Nice and convenient.

Brendan

Just what we were looking for. We wanted something to seamlessly replace a 'dir' command from someone else's code, and it worked just as advertised. Saved my colleague hours of work. After execution, we had to trim the output.name fields to include only the relative path to the current directory, rather than the full path.

Rakshit Kothari

Amazing!! exactly what I was looking for! Thank you very much :D

Michael

Incredibly useful tool! I love how simple it is. Thanks!

Brad Stiritz

Perfect! Just what I needed. Very appreciated, thank you :)

Kelly Kearney

Derek,

I think your comment must apply to a different submission; the lines you mention are not part of the file offered here. This version should be fully platform-independent (and was developed on a Mac, so would be Mac/Unix-biased if anything).

derek

There is one small issue on this file that is easily fixed. This script will only work on windows, because on line 25:
d=[d; {[rootpath '\' dnew(i).name]}];
and line 46:
d=[d; {[dtemp '\' dnew(i).name]}];

The backslash is the file separator only for window, for unix/linux this will cause problems because the file separator is '/'. This problem can easily be fixed by using filesep instead of '\'. i.e.:
d=[d; {[rootpath filesep dnew(i).name]}];
d=[d; {[dtemp filesep dnew(i).name]}];

Raj Sodhi

It works great!.

>> a = subdir([pwd '\*level1*.csv'])

a =

19x1 struct array with fields:
name
date
bytes
isdir
datenum

My only problem when I started using it was that it really does require an extension.

>> a = subdir([pwd '\*level1*'])
??? Undefined function or variable "filter".

Error in ==> subdir at 90
NewFiles = dir(fullfile(pathfolders{ifolder}, filter));

>>

I started troubleshooting and realized that the var filter never got defined on line 71 or 74.

Thanks for your file! Really elegant code.

yours,

Raj

MATLAB Release Compatibility
Created with R14SP3
Compatible with any release
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

subdir