-
Notifications
You must be signed in to change notification settings - Fork 13
/
dirr.m
279 lines (261 loc) · 9.14 KB
/
dirr.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
function [list,sumbytes,varargout] = DIRR(chemin,varargin)
%
%
% DIRR
% Lists all files in the current directory and sub directories
% recursively.
%
% [LIST] = DIRR(PATH)
% Returns a structure LIST with the same fieldnames as returned
% by LIST = DIR(PATH)
% PATH can contain wildcards * and ? after the last \ or / (filename
% filter)
% The content of each directory in PATH is listed inside its 'isdir'
% field with the same format. The 'bytes' field is NOT zero but the
% sum of all filesizes inside the directory.
%
% [LIST,BYTES] = DIRR(PATH)
% BYTES is a structure with fields 'total' and 'dir'. 'total' is the total
% size of PATH. 'dir' is a recursive substructure that contains the
% same fields ('total' and 'dir') for the subdirectories.
%
% [...] = DIRR(PATH,FILTER)
% Lists only files matching the string FILTER (non case sensitive
% regular expression).
% N.B.: FILTER is optional and must not be equal to a fieldname
% ('name' or 'date' ... will never be interpreted as filters)
%
% [LIST,BYTES,FIELDOUT] = DIRR(PATH,FIELDIN, ...)
% FIELDIN is a string specifying a field (of the structure LIST) that
% will be listed in a separate cell array of strings in FIELDOUT for
% every file with absolute path at the begining of the string.
% Multiple fields can be specified.
%
% [LIST,BYTES,FIELDOUT] = DIRR(PATH,FIELDIN,FILTER, ...)
% Only files for which FIELDIN matches FILTER will be returned.
% Multiple [FIELDIN, FILTER] couples may be specified.
% Recursion can be avoided here by setting 'isdir' filter to '0'.
% For bytes, numeric comparison will be performed.
%
%
% EXAMPLES :
%
% DIRR
% Lists all files (including path) in the current directory and it's
% subdirectories recursively.
%
% DIRR('c:\matlab6p5\work\*.m')
% Lists all M-files in the c:\matlab6p5\work directory and it's
% subdirectories recursively.
%
% Music = DIRR('G:\Ma musique\&Styles\Reggae\Alpha Blondy')
% Returns a structure Music very similar to what DIR returns
% but containing the information on the files stored in
% subdirectories of 'G:\Ma musique\&Styles\Reggae\Alpha Blondy'.
% The structure Music is a bit difficult to explore though.
% See next examples.
%
% [Files,Bytes,Names] = DIRR('c:\matlab6p5\toolbox','\.mex\>','name')
% Lists all MEX-files in the c:\matlab6p5\toolbox directory in the cell
% array of strings Names (including path).
% Note the regexp syntax of the filter string.
% Bytes is a structure with fields "total" and "dir". total is the
% total size of the directory, dir is a recursive substructure with
% the same fields as bytes for the subdirectories.
%
% [Files,Bytes,Names] = DIRR('c:\toto'...
% ,'name','bytes','>50000','isdir','0')
% Lists all files larger than 50000 bytes NOT recursively.
%
% [Files,Bytes,Dates] = DIRR('c:\matlab6p5\work','date','2005')
% Lists all dates of files from year 2005. (With path in front of
% date in the cell array of strings Dates)
%
%
%
% v1.02
% Maximilien Chaumon
% maximilien.chaumon@chups.jussieu.fr
% 2006 06 16
verbose = 0;
% set to 1 to get folders list in command window
if nargin == 0
chemin = cd;
end
if nargout == 0
dum = varargin;
varargin{1} = 'name';
varargin = [varargin(1) dum];
end
fields = {'name' 'date' 'bytes' 'isdir'};
if regexp(chemin,'[\*\?]') % if chemin contains any ? or *
filt = regexprep(chemin,'.*[\\/](.*\>)','$1');% get filter
filt = regexprep(filt,'\.','\.');% in regexp format
filt = regexprep(filt,'\*','.*');
filt = regexprep(filt,'\?','.');
filt = regexprep(filt,'(.*)','\\<$1');
chemin = regexprep(chemin,'(.*)[\\/].*\>','$1');% and chemin
end
if not(isempty(varargin)) % if additional fields were provided after chemin
for i = 1:length(fields)
if strcmp(varargin{1},fields{i})% if first varargin matches a fieldname,
% assume no filter was provided,
if not(exist('filt','var'))% or it was in chemin and was set just before
filt = '.*';% set it to wildcard
break
end
end
end
if not(exist('filt','var'))% else
filt = varargin{1};% first varargin is the filter
varargin(1) = [];
end
else% if no additional fields were provided and filter was not in chemin
if not(exist('filt','var'))
filt = '.*';
end
end
% determine which varargin are fieldnames
whicharefields = zeros(1,length(varargin));
for i = 1:length(varargin)
for j = 1:length(fields)
if strcmp(varargin{i},fields{j})
whicharefields(i) = 1;
break
end
end
end
% set f2out and f2outfilt
f2out = {}; f2outfilt = {};
idx = 0;
if not(isempty(varargin))
for i = 1:length(varargin)
if whicharefields(i)
idx = idx + 1;
f2out{idx} = varargin{i};
f2outfilt{idx} = '';
else % if nargin{i} is not a fieldname, assume it's a filter
f2outfilt{idx} = varargin{i};
end
end
end
%%%%%%%%%%%%%%%%%%%% START
if verbose
disp(chemin);
end
list = dir(chemin);
if isempty(list)
disp([chemin ' not found']);
if nargout == 0
clear list
else
for i = 1:nargout - 2
varargout{i} = [];
end
sumbytes = 0;
end
return
end
% remove . and ..
i_file = 1;
while i_file <= length(list)
if strcmp(list(i_file).name,'.')|strcmp(list(i_file).name,'..')
list(i_file) = [];
else
i_file = i_file + 1;
end
end
% set sumbytes
sumbytes = struct('total',0,'dir',{});
sumbytes(1).total = 0;
i_dir = 0;
% and all output fields
for i = 1:size(f2out,2)
f2out{2,i} = {};
end
filenames = {};
todel = 0;
r = 1;
for i_out = 1:size(f2out,2)
if strcmp(f2out{1,i_out},'isdir')
if strcmp(f2outfilt{i_out},'0') % check if no recursion is wanted
r = 0;
end
end
end
% for each item in list
for i_file = 1:length(list)
for i_out = 1:size(f2out,2) % for every output field
if not(isempty(f2outfilt{i_out}))% if there is a filter
if strcmp(f2out{1,i_out},'bytes') % if field is 'bytes'
line = [num2str(list(i_file).(f2out{1,i_out})) f2outfilt{i_out} ';']; % compare with filter numerically
if eval(line)% if passes the filter
continue % continue to next field
else
todel(end+1) = i_file; % else set to be deleted
end
elseif not(strcmp(f2out{1,i_out},'isdir'))% if field is 'name' or 'date'
if regexpi(list(i_file).(f2out{1,i_out}),f2outfilt{i_out}) % apply filter
continue % continue to next field
else
todel(end+1) = i_file; % else set to be deleted
end
end
end
end
% once checked for every field's filter
if todel(end) == i_file % if one didn't pass,
if not(list(i_file).isdir) % and it's not a directory
continue % skip this file and continue
end
else
if regexpi(list(i_file).name,filt) % else, check for general filter on filename
sumbytes(1).total = sumbytes(1).total + list(i_file).bytes; % sum bytes of that level
for i_out = 1:size(f2out,2)% and assign all output fields with the values of that file
f2out{2,i_out}{end+1} = [chemin filesep num2str(list(i_file).(f2out{1,i_out}))];
end
else
todel(end+1) = i_file; % else the file will be removed from the list structure
end
end
if list(i_file).isdir % if it's a directory
if not(r)
continue
end
i_dir = i_dir + 1;
cheminext = strcat(chemin,filesep,list(i_file).name);
% get it's content by recursion
% write the line to enter eval
line = '[list(i_file).isdir,sumbytes.dir(i_dir)';
for i_out = 1:size(f2out,2)% with all the requested fields as temporary variables
line = [line ',f2outtemp{' num2str(i_out) '}'];
end
line = [line '] = dirr(cheminext,filt'];
for i_out = 1:size(f2out,2)
line = [line ',f2out{1,' num2str(i_out) '}'];
if f2outfilt{i_out}
line = [line ',f2outfilt{' num2str(i_out) '}'];
end
end
line = [line ');'];
eval(line);
for i_out = 1:size(f2out,2)
f2out{2,i_out} = [f2out{2,i_out} f2outtemp{i_out}]; % catenate temporary variables with f2out
end
% sum bytes
sumbytes(1).total = sumbytes(1).total + sumbytes(1).dir(i_dir).total; % that level + the next one
list(i_file).bytes = sumbytes(1).dir(i_dir).total; % and set list(i_file).bytes to that value
if list(i_file).bytes & todel(end) == i_file
todel(end) = [];
end
end
end
todel(1) = [];
list(todel) = [];
for i_out = 1:size(f2out,2)
varargout{i_out} = f2out{2,i_out};
end
if nargout == 0
clear list
disp(char(f2out{2,1}));
end