1 | % GREP |
---|
2 | % a unix-like, very fast utility to find patterns |
---|
3 | % in any files in folders and their subfolders |
---|
4 | % |
---|
5 | % SYNTAX |
---|
6 | % help |
---|
7 | % GREP show this screen |
---|
8 | % GREP -p show extended help for PATTERN/FILE |
---|
9 | % GREP -f show contents of output structure P |
---|
10 | % GREP -e show examples |
---|
11 | % search |
---|
12 | % GREP PATTERN FILE(*) |
---|
13 | % GREP OPT1 ... OPTn PATTERN FILE(*) |
---|
14 | % [FL,P] = GREP(PATTERN,FILE(*)) |
---|
15 | % [FL,P] = GREP({PATTERN(s)},{FILE1(*),...,FILEn(*)}) |
---|
16 | % [FL,P] = GREP(OPT1,...,OPTn,PATTERN,FILE) |
---|
17 | % [FL,P] = GREP(OPT1,...,OPTn,{PATTERN(s)},{FILE1(*),...,FILEn(*)}) |
---|
18 | % |
---|
19 | % OPT : arg processing |
---|
20 | % --------------------------------------------------------------------------------- |
---|
21 | % -c : prints only a count of the lines that contain the pattern(s) |
---|
22 | % -D : debug mode: shows major processing steps |
---|
23 | % -d : debug mode: shows all processing steps |
---|
24 | % -da : debug mode: shows all output including debug messages |
---|
25 | % -e : PL searches for a string in pattern-list PL or {PL1,...,PLn} |
---|
26 | % : {PL} useful syntax when the string contains an option flag character (-) |
---|
27 | % multiple instances of <-e PL> and/or <-e {PL,...}> may be listed |
---|
28 | % PL searches for the first token in pattern without white spaces |
---|
29 | % {PL} searches for complete pattern(s) including white spaces |
---|
30 | % -f : PF takes the list of patterns from ASCII pattern-file PF |
---|
31 | % each line defines a single pattern that may include white spaces |
---|
32 | % -i : ignores upper/lower case distinction during comparisons |
---|
33 | % -I? : IL only includes folders/files with at least one matching pattern |
---|
34 | % {IL} from IL or {IL1,...ILn}, which may include regular expressions |
---|
35 | % multple instances of <-I? IL> and/or <I? {IL,...}> may be listed |
---|
36 | % -Id : searches for inclusions in folders |
---|
37 | % -If : searches for inclusions in file names |
---|
38 | % -Ip : searches for inclusions in full paths: folder/filename |
---|
39 | % -l : prints the names of files with matching lines once |
---|
40 | % -n : precedes each line by its line number in the file |
---|
41 | % -Q : does not prefix output with file name |
---|
42 | % -R : uses the regular expression engine <regexp> [def: <strfind>] |
---|
43 | % -r : recursively searches in subfolder(s) |
---|
44 | % -s : works silently and displays only error messages |
---|
45 | % -u : does not produce underlined text |
---|
46 | % -V : prints name of each file before it is searched |
---|
47 | % -v : prints all lines except those that contain the pattern |
---|
48 | % -x : prints only lines that are matched entirely |
---|
49 | % -X? : XL excludes folders/files with at least one matching pattern |
---|
50 | % {XL} from XL or {XL1,...XLn}, which may include regular expressions |
---|
51 | % multple instances of <-X? XL> and/or <X? {XL,...}> may be listed |
---|
52 | % -Xd : searches for exclusions in folders |
---|
53 | % -Xf : searches for exclusions in file names |
---|
54 | % -Xp : searches for exclusions in full paths: folder/filename |
---|
55 | % |
---|
56 | % NOTES all folder separators are replaced by unix-style </> to facilitate |
---|
57 | % the use of regular expressions with <-I?|X?> options |
---|
58 | % <-I?|X?> options allow wildcard searches using regular expressions |
---|
59 | % clicking on underlined text opens the file at the matching line |
---|
60 | |
---|
61 | % created: |
---|
62 | % us 14-Jan-1987 |
---|
63 | % modified: |
---|
64 | % us 04-Apr-2006 00:31:57 |
---|
65 | |
---|
66 | %-------------------------------------------------------------------------------- |
---|
67 | function [pout,p]=grep(varargin) |
---|
68 | |
---|
69 | % program parameters |
---|
70 | tim=clock; |
---|
71 | ver='04-Apr-2006 00:31:57'; |
---|
72 | |
---|
73 | % option table |
---|
74 | com='command line'; |
---|
75 | otbl={ |
---|
76 | % flag inival nrpar defpar accum desc |
---|
77 | % ----------------------------------------------------------------------------------------- |
---|
78 | '-c' false 0 [] 0 'count matches' |
---|
79 | '-D' false 0 [] 0 'major proc steps' |
---|
80 | '-d' false 0 [] 0 'minor proc steps' |
---|
81 | '-da' false 0 [] 0 'show all ouput including proc steps' |
---|
82 | '-e' false 1 {} 1 'pattern list' |
---|
83 | '-f' false 1 com 0 'pattern file' |
---|
84 | '-i' false 0 [] 0 'ignore case' |
---|
85 | '-Id' false 1 {} 1 'only include folders with one matching token' |
---|
86 | '-If' false 1 {} 1 'only include files with one matching token' |
---|
87 | '-Ip' false 1 {} 1 'only include full paths with one matching token' |
---|
88 | '-l' false 0 [] 0 'print file name' |
---|
89 | '-n' false 0 [] 0 'print line number' |
---|
90 | '-Q' false 0 [] 0 'no file name prefix' |
---|
91 | '-R' false 0 [] 0 'regular expression engine' |
---|
92 | '-r' false 0 [] 0 'search in subfolders' |
---|
93 | '-s' false 0 [] 0 'quiet mode except error messages' |
---|
94 | '-u' false 0 [] 0 'does not produce underlined text' |
---|
95 | '-V' false 0 [] 0 'print file before search' |
---|
96 | '-v' false 0 [] 0 'print non-matching lines' |
---|
97 | '-x' false 0 [] 0 'complete match' |
---|
98 | '-Xd' false 1 {} 1 'exclude folders with matching token' |
---|
99 | '-Xf' false 1 {} 1 'exclude files with matching token' |
---|
100 | '-Xp' false 1 {} 1 'exclude full paths with matching token' |
---|
101 | }; |
---|
102 | |
---|
103 | if nargout |
---|
104 | pout=[]; |
---|
105 | end |
---|
106 | |
---|
107 | % initialize engine |
---|
108 | p=ini_par(ver,tim); |
---|
109 | [p,msg]=set_opt(otbl,p,varargin{:}); |
---|
110 | if ~isempty(msg) |
---|
111 | p=show_res(100,p,msg); |
---|
112 | if nargout |
---|
113 | pout=p; |
---|
114 | end |
---|
115 | return; |
---|
116 | end |
---|
117 | p.npat=p.opt.ns; |
---|
118 | p.pattern=p.opt.pattern(:); |
---|
119 | p.porigin=p.opt.f.val; |
---|
120 | |
---|
121 | % get subfolders |
---|
122 | p=show_res(-100,p,sprintf('GREP> searching folders ...')); |
---|
123 | t1=clock; |
---|
124 | p=get_folders(p); |
---|
125 | p.runtime(2)=etime(clock,t1); |
---|
126 | p=show_res( -99,p,sprintf('GREP> done %13.3f %d folder(s)',p.runtime(1),p.nfolder)); |
---|
127 | |
---|
128 | % get files |
---|
129 | if p.nfolder |
---|
130 | p=show_res( -98,p,sprintf('GREP> searching files ...')); |
---|
131 | t1=clock; |
---|
132 | p=get_files(p); |
---|
133 | p.runtime(3)=etime(clock,t1); |
---|
134 | p=show_res( -97,p,sprintf('GREP> done %13.3f %d file(s)',p.runtime(2),p.nfiles)); |
---|
135 | end |
---|
136 | |
---|
137 | if nargout |
---|
138 | pout=unique(p.files); |
---|
139 | end |
---|
140 | p=ini_par(p); |
---|
141 | return; |
---|
142 | %-------------------------------------------------------------------------------- |
---|
143 | %-------------------------------------------------------------------------------- |
---|
144 | % SUBROUTINES |
---|
145 | % - ehelp extended help engine |
---|
146 | % - ini_par initialize structure |
---|
147 | % - set_opt input parser |
---|
148 | % - get_folders harvest input folders |
---|
149 | % - get_folder harvest subfolders/input folder |
---|
150 | % - get_files harvest files/input folder |
---|
151 | % - get_file harvest files |
---|
152 | % - chk_path check file/folder inclusion/exclusion |
---|
153 | % - get_match look for matches |
---|
154 | % - update update arrays |
---|
155 | % - show_res common display engine |
---|
156 | % - show_entry final display engine |
---|
157 | %-------------------------------------------------------------------------------- |
---|
158 | %-------------------------------------------------------------------------------- |
---|
159 | function p=ehelp(p,fnam,tag) |
---|
160 | |
---|
161 | [fp,msg]=fopen(which(fnam),'rt'); |
---|
162 | if fp > 0 |
---|
163 | hs=fread(fp,inf,'*char').'; |
---|
164 | fclose(fp); |
---|
165 | ib=strfind(hs,tag); |
---|
166 | if isempty(ib) ||... |
---|
167 | numel(ib)<2 |
---|
168 | hs=sprintf('GREP> help sectio <%s> not found/not valid',tag); |
---|
169 | else |
---|
170 | hs=hs(ib(end-1)+length(tag)+1:ib(end)-1); |
---|
171 | hs=strrep(hs,p.par.hdel,''); |
---|
172 | end |
---|
173 | else |
---|
174 | hs=sprintf('%s: <%s>',msg,fnam); |
---|
175 | end |
---|
176 | disp(hs); |
---|
177 | return; |
---|
178 | %-------------------------------------------------------------------------------- |
---|
179 | function p=ini_par(ver,tim) |
---|
180 | |
---|
181 | % clean up |
---|
182 | if isstruct(ver) |
---|
183 | p=ver; |
---|
184 | tim=p.par.tim; |
---|
185 | p.nxfolder=p.par.chkex(1); |
---|
186 | p.nxfiles=p.par.chkex(2); |
---|
187 | p.nafolder=p.nfolder+p.nxfolder; |
---|
188 | p.nafiles=p.nfiles+p.nxfiles; |
---|
189 | p.mdepth=max(p.fdepth); |
---|
190 | if ~isempty(p.result) |
---|
191 | p.result=char(p.result); |
---|
192 | end |
---|
193 | if ~p.opt.D.flg &&... |
---|
194 | ~p.opt.d.flg |
---|
195 | p=rmfield(p,'par'); |
---|
196 | end |
---|
197 | p.runtime(1)=etime(clock,tim); |
---|
198 | return; |
---|
199 | end |
---|
200 | |
---|
201 | % initialize common structure |
---|
202 | % - parameters |
---|
203 | magic='GREP'; |
---|
204 | fsep='/'; |
---|
205 | |
---|
206 | % - special characters |
---|
207 | % - EOL UNIX = LF |
---|
208 | % - EOL WINDOWS = CR+LF |
---|
209 | par.tab=sprintf('\t'); % 009 = TAB: horizontal tab |
---|
210 | par.cr=sprintf('\r'); % 013 = CR: carriage return |
---|
211 | par.lf=sprintf('\n'); % 010 = LF: line feed |
---|
212 | par.fsep=fsep; |
---|
213 | par.isold=0; |
---|
214 | par.nbytes=0; |
---|
215 | par.nlines=0; |
---|
216 | par.mfc=1; |
---|
217 | par.mlc=1; |
---|
218 | par.cd=[]; |
---|
219 | par.cf=[]; |
---|
220 | par.cn=[]; |
---|
221 | par.cs=[]; |
---|
222 | par.s=[]; |
---|
223 | par.eol=[]; |
---|
224 | par.chkpath=false; % true if I[]/X[] flags are set |
---|
225 | par.chkex=[0,0]; |
---|
226 | par.hasmatch=false; |
---|
227 | par.nmatch=0; |
---|
228 | par.hdel='%$'; |
---|
229 | par.reft='<a href="matlab:opentoline(''%s'',%-1d)">%s</a>: %s'; |
---|
230 | par.tim=tim; |
---|
231 | |
---|
232 | % ID |
---|
233 | p.magic=magic; |
---|
234 | p.ver=ver; |
---|
235 | p.mver=version; |
---|
236 | p.rundate=datestr(tim); |
---|
237 | p.runtime=[0,0,0]; |
---|
238 | % parameters/options |
---|
239 | p.opt=[]; |
---|
240 | p.msg=[]; |
---|
241 | p.par=par; |
---|
242 | |
---|
243 | p.section_1='===== FOLDERS ====='; |
---|
244 | p.nfolder=0; |
---|
245 | p.nxfolder=0; |
---|
246 | p.nafolder=0; |
---|
247 | p.folder{1,1}=[]; |
---|
248 | p.fenum=[]; |
---|
249 | p.mdepth=0; |
---|
250 | p.fdepth(1,1)=0; |
---|
251 | p.section_2='===== PATTERNS ====='; |
---|
252 | p.npat=0; |
---|
253 | p.pattern={}; |
---|
254 | p.porigin={}; |
---|
255 | p.section_3='===== FILES ====='; |
---|
256 | p.nfiles=0; |
---|
257 | p.nxfiles=0; |
---|
258 | p.nafiles=0; |
---|
259 | p.nbytes=0; |
---|
260 | p.nlines=0; |
---|
261 | p.section_4='===== MATCHES ====='; |
---|
262 | p.mfiles=0; |
---|
263 | p.mbytes=0; |
---|
264 | p.mlines=0; |
---|
265 | p.pfiles=0; |
---|
266 | p.pcount=0; |
---|
267 | p.files={}; |
---|
268 | p.lcount=[]; |
---|
269 | p.findex=[]; |
---|
270 | p.pindex=[]; |
---|
271 | p.line=[]; |
---|
272 | p.match={}; |
---|
273 | p.result={}; |
---|
274 | return; |
---|
275 | %-------------------------------------------------------------------------------- |
---|
276 | function [p,msg]=set_opt(otbl,p,varargin) |
---|
277 | |
---|
278 | o=[]; |
---|
279 | msg=[]; |
---|
280 | |
---|
281 | % set options |
---|
282 | % ...default options |
---|
283 | o.des1='===== OPTIONS ====='; |
---|
284 | for i=1:size(otbl,1) |
---|
285 | fn=otbl{i,1}(2:end); |
---|
286 | o.(fn).flg=otbl{i,2}; |
---|
287 | o.(fn).acc=otbl{i,5}; |
---|
288 | o.(fn).des=otbl{i,6}; |
---|
289 | o.(fn).def=otbl{i,4}; |
---|
290 | o.(fn).val=otbl{i,4}; |
---|
291 | end |
---|
292 | |
---|
293 | argn=numel(varargin); |
---|
294 | if argn < 2 |
---|
295 | if ~argn |
---|
296 | help(mfilename); |
---|
297 | msg=sprintf('GREP> needs at least two arguments'); |
---|
298 | elseif numel(varargin{1}) > 1 |
---|
299 | switch lower(varargin{1}(1:2)) |
---|
300 | case {'-p'} |
---|
301 | ehelp(p,mfilename,'___FORMAT___'); |
---|
302 | msg=true; |
---|
303 | case {'-e'} |
---|
304 | ehelp(p,mfilename,'___EXAMPLE___'); |
---|
305 | msg=true; |
---|
306 | case {'-f'} |
---|
307 | ehelp(p,mfilename,'___OUTPUT___'); |
---|
308 | msg=true; |
---|
309 | otherwise |
---|
310 | help(mfilename); |
---|
311 | msg=sprintf('GREP> needs at least two arguments'); |
---|
312 | end |
---|
313 | else |
---|
314 | help(mfilename); |
---|
315 | msg=sprintf('GREP> needs at least two arguments'); |
---|
316 | end |
---|
317 | p.opt=o; |
---|
318 | return; |
---|
319 | end |
---|
320 | |
---|
321 | % ...user defined options |
---|
322 | % ...must account for syntax of various forms |
---|
323 | % ('-a -b +c -d','-f',xxx,'-g +h',...) |
---|
324 | |
---|
325 | % ...reconstruct <varargin> as a string |
---|
326 | pat=sprintf('GREP>ARG|%20.19f[',rand); |
---|
327 | arg=varargin; |
---|
328 | ic=cellfun(@(x) [pat,class(x),']'],arg,'uniformoutput',false); |
---|
329 | il=cellfun('isclass',arg,'char'); |
---|
330 | ic(il)=arg(il); |
---|
331 | ic=sprintf('%s ',ic{:}); |
---|
332 | ic=strread(ic,'%s'); |
---|
333 | [ox,io]=ismember(ic,otbl(:,1)); %#ok MLINT 2006a |
---|
334 | ox=io(io>0); |
---|
335 | ax=find(io); |
---|
336 | argn=numel(ic); |
---|
337 | iv=strfind(ic,pat); |
---|
338 | iv=~cellfun('isempty',iv); |
---|
339 | ic(iv)=arg(~il); |
---|
340 | |
---|
341 | for i=1:numel(ox) |
---|
342 | ix=ox(i); |
---|
343 | fn=otbl{ix,1}(2:end); |
---|
344 | o.(fn).flg=xor(otbl{ix,2},1); |
---|
345 | if otbl{ix,3} > 0 |
---|
346 | vx=ax(i)+1:ax(i)+otbl{ix,3}; |
---|
347 | if vx(end) <= argn |
---|
348 | if o.(fn).acc |
---|
349 | if ~iscell(ic(vx)) |
---|
350 | ic(vx)={ic(vx)}; |
---|
351 | o.(fn).val=[o.(fn).val;{ic(vx)}]; |
---|
352 | else |
---|
353 | o.(fn).val=[o.(fn).val,ic{vx}]; |
---|
354 | end |
---|
355 | else |
---|
356 | o.(fn).val=ic(vx); |
---|
357 | end |
---|
358 | else |
---|
359 | o.(fn).flg=otbl{ix,2}; |
---|
360 | msg=sprintf('GREP> parameter(s) missing for option <%s> [%-1d]',... |
---|
361 | otbl{ix,1},otbl{ix,3}); |
---|
362 | end |
---|
363 | end |
---|
364 | end |
---|
365 | |
---|
366 | if o.Id.flg ||... |
---|
367 | o.If.flg ||... |
---|
368 | o.Ip.flg ||... |
---|
369 | o.Xd.flg ||... |
---|
370 | o.Xf.flg ||... |
---|
371 | o.Xp.flg |
---|
372 | p.par.chkpath=true; |
---|
373 | end |
---|
374 | |
---|
375 | % get search template(s)/file(s) |
---|
376 | % ...templates |
---|
377 | o.des2='===== INPUT ====='; |
---|
378 | o.arg={}; |
---|
379 | o.ns=0; |
---|
380 | o.pattern=varargin{end-1}; |
---|
381 | o.nf=0; |
---|
382 | o.files=varargin{end}; |
---|
383 | |
---|
384 | if ~iscell(o.pattern) |
---|
385 | o.pattern={o.pattern}; |
---|
386 | end |
---|
387 | if o.e.flg |
---|
388 | o.pattern=o.e.val; |
---|
389 | end |
---|
390 | if o.f.flg |
---|
391 | if iscell(o.f.val{1}) |
---|
392 | o.f.val{1}=o.f.val{1}{:}; |
---|
393 | end |
---|
394 | pnam=o.f.val{1}; |
---|
395 | if exist(pnam,'file') |
---|
396 | o.pattern=textread(pnam,'%s','delimiter','\n','whitespace',''); |
---|
397 | else |
---|
398 | msg=sprintf('GREP> pattern file not existing <%s>',pnam); |
---|
399 | end |
---|
400 | end |
---|
401 | o.ns=numel(o.pattern); |
---|
402 | o.arg=ic; |
---|
403 | |
---|
404 | % ...files |
---|
405 | if ~iscell(o.files) |
---|
406 | o.files={o.files}; |
---|
407 | end |
---|
408 | o.files=o.files(:); |
---|
409 | o.ns=numel(o.pattern); |
---|
410 | o.nf=numel(o.files); |
---|
411 | |
---|
412 | for i=1:o.nf |
---|
413 | if isempty(o.files{i}) |
---|
414 | o.files{i}=[cd,p.par.fsep,'*.*']; |
---|
415 | end |
---|
416 | if o.files{i}(end)=='/' ||... |
---|
417 | o.files{i}(end)=='\' |
---|
418 | o.files{i}=o.files{i}(1:end-1); |
---|
419 | end |
---|
420 | o.fpat{i}=o.files{i}; |
---|
421 | o.fnam{i}='*.*'; |
---|
422 | o.fext{i}='.*'; |
---|
423 | if strcmp(o.fpat{i},'.') |
---|
424 | o.fpat{i}=cd; |
---|
425 | end |
---|
426 | if ~exist(o.files{i},'dir') |
---|
427 | [o.fpat{i},o.fnam{i},o.fext{i}]=fileparts(o.files{i}); |
---|
428 | if isempty(o.fpat{i}) |
---|
429 | o.fpat{i}=cd; |
---|
430 | end |
---|
431 | if isempty(o.fnam{i}) |
---|
432 | o.fnam{i}='*'; |
---|
433 | end |
---|
434 | if isempty(o.fext{i}) |
---|
435 | o.fext{i}='.*'; |
---|
436 | end |
---|
437 | o.fnam{i}=[o.fnam{i},o.fext{i}]; |
---|
438 | end |
---|
439 | end |
---|
440 | |
---|
441 | % ...remove dup folders |
---|
442 | o.npat=0; |
---|
443 | o.xpat=1; |
---|
444 | o.upat=1; |
---|
445 | [o.fpat,ix]=sort(o.fpat(:)); |
---|
446 | o.files=o.files(ix); |
---|
447 | o.fnam=o.fnam(ix); |
---|
448 | o.fext=o.fext(ix); |
---|
449 | [o.npat,o.npat,o.xpat]=unique(o.fpat); |
---|
450 | o.npat=numel(o.npat); |
---|
451 | o.upat=find([1;diff(o.xpat)]>0); |
---|
452 | |
---|
453 | p.opt=o; |
---|
454 | return; |
---|
455 | %-------------------------------------------------------------------------------- |
---|
456 | function p=get_folders(p) |
---|
457 | |
---|
458 | for i=1:p.opt.npat |
---|
459 | cf=p.opt.fpat{p.opt.upat(i)}; |
---|
460 | cf=strrep(cf,filesep,p.par.fsep); |
---|
461 | p=get_folder(p,cf,cf,0,i); |
---|
462 | end |
---|
463 | return; |
---|
464 | %-------------------------------------------------------------------------------- |
---|
465 | function p=get_folder(p,frot,crot,depth,ix) |
---|
466 | |
---|
467 | % recursively find all subfolders of a root |
---|
468 | % note we CANNOT use <genpath> as it does not return all subfolders! |
---|
469 | % eg, |
---|
470 | % - @class subfolders |
---|
471 | % - private subfolders |
---|
472 | |
---|
473 | % root folders |
---|
474 | if ~depth |
---|
475 | p=show_res(-10,p,sprintf('GREP> folder <%s>',frot)); |
---|
476 | if exist(frot,'dir') |
---|
477 | [tf,p]=chk_path(1,p,frot,'***FOLDER***'); |
---|
478 | if tf |
---|
479 | p.nfolder=p.nfolder+1; |
---|
480 | p.folder{p.nfolder,1}=strrep(frot,filesep,p.par.fsep); |
---|
481 | p.fenum(p.nfolder,1)=ix; |
---|
482 | end |
---|
483 | else |
---|
484 | msg=sprintf('GREP> folder not found <%s>',frot); |
---|
485 | p=show_res(100,p,msg); |
---|
486 | end |
---|
487 | end |
---|
488 | |
---|
489 | if ~p.opt.r.flg |
---|
490 | return; |
---|
491 | end |
---|
492 | |
---|
493 | % subfolders |
---|
494 | rd=dir(crot); |
---|
495 | rx=[rd.isdir]==1; |
---|
496 | rd=rd(rx); |
---|
497 | nd=numel(rd); |
---|
498 | for i=1:nd |
---|
499 | if rd(i).isdir && ~all(rd(i).name=='.') % rd(i).name(1) ~= '.' |
---|
500 | if ~isempty(crot) |
---|
501 | nrot=[crot,p.par.fsep,rd(i).name]; |
---|
502 | else |
---|
503 | nrot=rd(i).name; |
---|
504 | end |
---|
505 | nrot=strrep(nrot,filesep,p.par.fsep); |
---|
506 | [tf,p]=chk_path(1,p,nrot,'***SUBFOLDER***'); |
---|
507 | if tf |
---|
508 | p.nfolder=p.nfolder+1; |
---|
509 | depth=depth+1; |
---|
510 | p.fdepth(p.nfolder,1)=depth; |
---|
511 | p.folder{p.nfolder,1}=strrep(nrot,filesep,p.par.fsep); |
---|
512 | p.fenum(p.nfolder,1)=ix; |
---|
513 | p=show_res(-9,p,sprintf('- subfolder %5d/%6d <%s>',depth,p.nfolder,nrot)); |
---|
514 | p=get_folder(p,frot,nrot,depth,ix); |
---|
515 | depth=depth-1; |
---|
516 | end |
---|
517 | end |
---|
518 | end |
---|
519 | if ~depth |
---|
520 | p.par.isold=0; |
---|
521 | end |
---|
522 | return; |
---|
523 | %-------------------------------------------------------------------------------- |
---|
524 | function p=get_files(p) |
---|
525 | |
---|
526 | for i=1:p.opt.nf |
---|
527 | cn=p.opt.fnam{i}; |
---|
528 | fx=find(p.fenum==p.opt.xpat(i)); |
---|
529 | cp=p.folder(fx); |
---|
530 | for j=1:numel(fx) |
---|
531 | p.par.cd=cp{j}; |
---|
532 | p=show_res(-8,p,sprintf('GREP> files %5d/%7d <%s:%s>',i,j,p.par.cd,cn)); |
---|
533 | d=dir([p.par.cd,p.par.fsep,cn]); |
---|
534 | if ~isempty(d) |
---|
535 | for k=1:numel(d) |
---|
536 | if ~d(k).isdir |
---|
537 | p.par.cf=[p.par.cd,p.par.fsep,d(k).name]; |
---|
538 | p.par.cn=d(k).name; |
---|
539 | [tf,p]=chk_path(2,p,p.par.cf,p.par.cn); |
---|
540 | if tf |
---|
541 | p=show_res(-7,p,sprintf('- file %7d/%7d <%s>',k,numel(d),p.par.cf)); |
---|
542 | p=get_file(p); |
---|
543 | end |
---|
544 | end |
---|
545 | end |
---|
546 | end |
---|
547 | end |
---|
548 | end |
---|
549 | return; |
---|
550 | %-------------------------------------------------------------------------------- |
---|
551 | function p=get_file(p) |
---|
552 | |
---|
553 | %D if exist(p.par.cf,'file') |
---|
554 | [fp,msg]=fopen(p.par.cf,'rb'); |
---|
555 | if fp < 0 |
---|
556 | msg=sprintf('GREP> cannot open file <%s>\nGREP> %s',p.par.cf,msg); |
---|
557 | p=show_res(100,p,msg); |
---|
558 | else |
---|
559 | p.par.s=fread(fp,inf,'*char').'; |
---|
560 | fclose(fp); |
---|
561 | p.par.nbytes=numel(p.par.s); |
---|
562 | if ispc |
---|
563 | p.par.s=strrep(p.par.s,[p.par.cr,p.par.lf],p.par.lf); |
---|
564 | end |
---|
565 | p.par.s=strrep(p.par.s,char(0),'^'); |
---|
566 | p=show_res(2,p); |
---|
567 | p=get_match(p); |
---|
568 | end |
---|
569 | %D end |
---|
570 | return; |
---|
571 | %-------------------------------------------------------------------------------- |
---|
572 | function [tf,p]=chk_path(mode,p,fnam,frot) |
---|
573 | |
---|
574 | tf=true; |
---|
575 | % - escape immediately if user did not choose inclusion/exclusion flags |
---|
576 | if ~p.par.chkpath |
---|
577 | return; |
---|
578 | end |
---|
579 | |
---|
580 | ixi=true; |
---|
581 | ixe=false; |
---|
582 | switch mode |
---|
583 | % include/exclude folders |
---|
584 | case 1 |
---|
585 | smode='FOLDER'; |
---|
586 | if p.opt.Id.flg |
---|
587 | ix=regexp(fnam,p.opt.Id.val); |
---|
588 | ixi=any(~cellfun('isempty',ix)); |
---|
589 | end |
---|
590 | if ixi |
---|
591 | if p.opt.Xd.flg |
---|
592 | ix=regexp(fnam,p.opt.Xd.val); |
---|
593 | ixe=any(~cellfun('isempty',ix)); |
---|
594 | end |
---|
595 | end |
---|
596 | % incrementally include/exclude files/full paths |
---|
597 | case 2 |
---|
598 | smode='FILE'; |
---|
599 | if p.opt.If.flg |
---|
600 | ix=regexp(frot,p.opt.If.val); |
---|
601 | ixi=any(~cellfun('isempty',ix)); |
---|
602 | end |
---|
603 | if ixi |
---|
604 | if p.opt.Xf.flg |
---|
605 | ix=regexp(frot,p.opt.Xf.val); |
---|
606 | ixe=any(~cellfun('isempty',ix)); |
---|
607 | end |
---|
608 | if ~ixe |
---|
609 | smode='PATH'; |
---|
610 | if p.opt.Ip.flg |
---|
611 | ix=regexp(fnam,p.opt.Ip.val); |
---|
612 | ixi=any(~cellfun('isempty',ix)); |
---|
613 | end |
---|
614 | if ixi |
---|
615 | if p.opt.Xp.flg |
---|
616 | ix=regexp(fnam,p.opt.Xp.val); |
---|
617 | ixe=any(~cellfun('isempty',ix)); |
---|
618 | end % does not match PATH Xp |
---|
619 | end % does not macht PATH Ip |
---|
620 | end % does not match FILE Xf |
---|
621 | end % does not match FILE If |
---|
622 | |
---|
623 | end % switch |
---|
624 | |
---|
625 | if ~ixi ||... |
---|
626 | ixe |
---|
627 | p.par.chkex(mode)=p.par.chkex(mode)+1; |
---|
628 | p=show_res(-50,p,sprintf('* exclude %7.7s <%s>',smode,fnam)); |
---|
629 | tf=false; |
---|
630 | end |
---|
631 | return; |
---|
632 | %-------------------------------------------------------------------------------- |
---|
633 | function p=get_match(p) |
---|
634 | |
---|
635 | p.par.hasmatch=false; |
---|
636 | s=p.par.s; |
---|
637 | if p.opt.i.flg |
---|
638 | s=lower(s); |
---|
639 | end |
---|
640 | % find EOL marker(s) |
---|
641 | p.par.eol=[0,strfind(s,p.par.lf),numel(s)+1]; |
---|
642 | p.par.nlines=numel(p.par.eol)-2; |
---|
643 | p.nfiles=p.nfiles+1; |
---|
644 | p.nbytes=p.nbytes+p.par.nbytes; |
---|
645 | p.nlines=p.nlines+p.par.nlines; |
---|
646 | |
---|
647 | for j=1:p.opt.ns |
---|
648 | str=p.opt.pattern{j}; |
---|
649 | if p.opt.i.flg |
---|
650 | str=lower(str); |
---|
651 | end |
---|
652 | p.par.cs=str; |
---|
653 | |
---|
654 | % find string pattern <str> |
---|
655 | if p.opt.R.flg |
---|
656 | ix=regexp(s,str); |
---|
657 | else |
---|
658 | ix=strfind(s,str); |
---|
659 | end |
---|
660 | |
---|
661 | p.par.nmatch=0; |
---|
662 | if ~isempty(ix) |
---|
663 | |
---|
664 | % ...find line(s) |
---|
665 | [lx,lx]=histc(ix,p.par.eol); %#ok MLINT 2006a |
---|
666 | lx=lx(find([diff(lx),1])); %#ok MLINT 2006a |
---|
667 | |
---|
668 | % ...-v: only print non-matching lines |
---|
669 | if p.opt.v.flg |
---|
670 | tl=1:numel(p.par.eol)-2; |
---|
671 | ll=tl~=0; |
---|
672 | ll(lx)=false; |
---|
673 | lx=tl(ll); |
---|
674 | end |
---|
675 | |
---|
676 | nx=numel(lx); |
---|
677 | if nx |
---|
678 | p=show_res(-2,p,lx,0); |
---|
679 | for i=1:nx |
---|
680 | sx=p.par.eol(lx(i))+1:p.par.eol(lx(i)+1)-1; |
---|
681 | nl=lx(i); |
---|
682 | nm=p.par.s(sx); |
---|
683 | |
---|
684 | % ...-x: only print fully matching lines |
---|
685 | if ~p.opt.x.flg ||... |
---|
686 | numel(sx)==numel(str) |
---|
687 | p.par.nmatch=p.par.nmatch+1; |
---|
688 | p=show_res(3,p,nl,nm); |
---|
689 | if ~p.opt.c.flg ||... |
---|
690 | i==1 |
---|
691 | p=update(3,p,nl,nm); |
---|
692 | end |
---|
693 | end |
---|
694 | end % each match |
---|
695 | end % found match |
---|
696 | end % found matches |
---|
697 | |
---|
698 | if p.par.nmatch |
---|
699 | p.par.hasmatch=true; |
---|
700 | p.pfiles=p.pfiles+1; |
---|
701 | p.pcount=p.pcount+nx; |
---|
702 | p.files(p.pfiles,1)={p.par.cf}; |
---|
703 | p.lcount(p.pfiles,1)=nx; |
---|
704 | p.findex=[p.findex;repmat(p.pfiles,nx,1)]; |
---|
705 | p.pindex=[p.pindex;repmat(j,nx,1)]; |
---|
706 | if p.opt.c.flg |
---|
707 | p=show_res(4,p); |
---|
708 | end |
---|
709 | end |
---|
710 | |
---|
711 | end % for each <string> |
---|
712 | |
---|
713 | if p.par.hasmatch |
---|
714 | p.mfiles=p.mfiles+1; |
---|
715 | p.mbytes=p.mbytes+p.par.nbytes; |
---|
716 | p.mlines=p.mlines+p.par.nlines; |
---|
717 | end |
---|
718 | |
---|
719 | return; |
---|
720 | %-------------------------------------------------------------------------------- |
---|
721 | function p=update(mode,p,varargin) |
---|
722 | |
---|
723 | switch mode |
---|
724 | case 3 |
---|
725 | p.line(p.par.mlc,1)=varargin{1}; |
---|
726 | p.match(p.par.mlc,1)={varargin{2}}; |
---|
727 | p.par.mlc=p.par.mlc+1; |
---|
728 | case 4 |
---|
729 | p.result(p.par.mfc,1)={varargin{1}}; |
---|
730 | p.par.mfc=p.par.mfc+1; |
---|
731 | end |
---|
732 | return; |
---|
733 | %-------------------------------------------------------------------------------- |
---|
734 | function p=show_res(mode,p,varargin) |
---|
735 | |
---|
736 | % common output engine |
---|
737 | |
---|
738 | % mode display entity |
---|
739 | % -100 subfolder engine start |
---|
740 | % -99 subfolder engine end |
---|
741 | % -98 match engine start |
---|
742 | % -97 match engine end |
---|
743 | % -50 exclude folder/file |
---|
744 | % -10 folder |
---|
745 | % -9 subfolder |
---|
746 | % -8 current folder |
---|
747 | % -7 current file |
---|
748 | % -2 match |
---|
749 | % 2 file before search |
---|
750 | % 3 line |
---|
751 | % 4 line count only |
---|
752 | % 100 error message |
---|
753 | |
---|
754 | % display all ouput |
---|
755 | if p.opt.da.flg |
---|
756 | p=show_entry(mode,p,varargin{:}); |
---|
757 | return; |
---|
758 | end |
---|
759 | |
---|
760 | % display selected ouput only |
---|
761 | if p.opt.s.flg &&... |
---|
762 | mode < 100 |
---|
763 | return; |
---|
764 | else |
---|
765 | if mode < -10 |
---|
766 | if ~p.opt.D.flg &&... |
---|
767 | ~p.opt.d.flg |
---|
768 | return; |
---|
769 | end |
---|
770 | elseif mode < 0 |
---|
771 | if ~p.opt.d.flg |
---|
772 | return; |
---|
773 | end |
---|
774 | end |
---|
775 | end |
---|
776 | p=show_entry(mode,p,varargin{:}); |
---|
777 | return; |
---|
778 | %-------------------------------------------------------------------------------- |
---|
779 | function p=show_entry(mode,p,varargin) |
---|
780 | |
---|
781 | str=[]; |
---|
782 | txt=[]; %#ok MLINT 2006a |
---|
783 | ref=[]; |
---|
784 | switch mode |
---|
785 | case {-100 -99 -98 -97 -50 -10 -9 -8 -7} |
---|
786 | str=varargin{1}; |
---|
787 | case -2 |
---|
788 | str=sprintf('+ match %16d <%s>',numel(varargin{1}),p.par.cf); |
---|
789 | case 2 |
---|
790 | if p.opt.V.flg |
---|
791 | str=sprintf('%s',p.par.cf); |
---|
792 | end |
---|
793 | case 3 |
---|
794 | if p.opt.l.flg &&... |
---|
795 | p.par.nmatch==1 |
---|
796 | str=sprintf('%s [%s]',p.par.cf,p.par.cs); |
---|
797 | end |
---|
798 | if ~p.opt.c.flg |
---|
799 | if p.opt.D.flg ||... |
---|
800 | p.opt.d.flg |
---|
801 | ref=sprintf('%17d',varargin{1}); |
---|
802 | txt=sprintf('%17d: <%s>',varargin{1},varargin{2}); |
---|
803 | elseif p.opt.n.flg &&... |
---|
804 | ~p.opt.Q.flg |
---|
805 | ref=sprintf('%s:%-1d',p.par.cn,varargin{1}); |
---|
806 | txt=sprintf('%s:%-1d: %s',p.par.cn,varargin{1},varargin{2}); |
---|
807 | elseif p.opt.n.flg &&... |
---|
808 | p.opt.Q.flg |
---|
809 | ref=sprintf('%-1d',varargin{1}); |
---|
810 | txt=sprintf('%-1d: %s',varargin{1},varargin{2}); |
---|
811 | elseif ~p.opt.Q.flg |
---|
812 | ref=sprintf('%s',p.par.cn); |
---|
813 | txt=sprintf('%s: %s',p.par.cn,varargin{2}); |
---|
814 | else |
---|
815 | txt=sprintf('%s',varargin{2}); |
---|
816 | end |
---|
817 | if ~isempty(ref) |
---|
818 | if ~p.opt.u.flg |
---|
819 | txt=sprintf(p.par.reft,p.par.cf,varargin{1},ref,varargin{2}); |
---|
820 | end |
---|
821 | end |
---|
822 | if ~isempty(str) |
---|
823 | str=str2mat(str,txt); |
---|
824 | else |
---|
825 | str=txt; |
---|
826 | end |
---|
827 | end |
---|
828 | case 4 |
---|
829 | if p.opt.c.flg |
---|
830 | str=sprintf('%-d',p.lcount(p.pfiles)); |
---|
831 | end |
---|
832 | case 100 |
---|
833 | p.msg=varargin{1}; |
---|
834 | if ischar(p.msg) |
---|
835 | str=p.msg; |
---|
836 | end |
---|
837 | end |
---|
838 | |
---|
839 | if ~isempty(str) |
---|
840 | p=update(4,p,str); |
---|
841 | disp(str); |
---|
842 | end |
---|
843 | return; |
---|
844 | %-------------------------------------------------------------------------------- |
---|
845 | %-------------------------------------------------------------------------------- |
---|
846 | % EXTENDED HELP SECTION |
---|
847 | % formatted for pretty output |
---|
848 | % do NOT change alignment |
---|
849 | %-------------------------------------------------------------------------------- |
---|
850 | % BOL delimiter %$ |
---|
851 | % tag contents |
---|
852 | % ___FORMAT___ input formats |
---|
853 | % ___OUTPUT___ P.field explanations |
---|
854 | % ___EXAMPLE___ examples |
---|
855 | |
---|
856 | %{ |
---|
857 | %$___FORMAT___ |
---|
858 | %$ SYNTAX |
---|
859 | %$ grep PATTERN FILE |
---|
860 | %$ grep OPT1 ... OPTn PATTERN FILE |
---|
861 | %$ [FL,P] = grep(PATTERN,FILE) |
---|
862 | %$ [FL,P] = grep({PATTERN(s)}, {FILE(s)}) |
---|
863 | %$ [FL,P] = grep(OPT1, ..., OPTn, PATTERN, FILE) |
---|
864 | %$ [FL,P] = grep(OPT1,...,OPTn,{PATTERN(s)},{FILE(s)}) |
---|
865 | %$ |
---|
866 | %$ input arguments/formats |
---|
867 | %$ --------------------------------------------------------------------------------- |
---|
868 | %$ OPT |
---|
869 | %$ --------------------------------------------------------------------------------- |
---|
870 | %$ for available options, |
---|
871 | %$ see <grep> or <help grep> |
---|
872 | %$ |
---|
873 | %$ any mixture of ...,'-a -b -d','-k','-y -z',... |
---|
874 | %$ |
---|
875 | %$ note the input parser will tokenize strings |
---|
876 | %$ into single options and other arguments |
---|
877 | %$ see: <P.opt.arg> for parsing results |
---|
878 | %$ |
---|
879 | %$ special cases |
---|
880 | %$ |
---|
881 | %$ -e '-e -l' |
---|
882 | %$ add pattern <-l> AND set option [-l] |
---|
883 | %$ '-e',{'-n'} |
---|
884 | %$ add pattern <-n> do NOT set option [-n] |
---|
885 | %$ -e 'this is' |
---|
886 | %$ by definition will only search for <this> |
---|
887 | %$ -e {'this is','a test'} |
---|
888 | %$ will first search for <this is> |
---|
889 | %$ than <a test> |
---|
890 | %$ -s silent mode will run much(!) faster |
---|
891 | %$ results can easily be extracted from P |
---|
892 | %$ see: <grep -f> for information |
---|
893 | %$ |
---|
894 | %$ inclusion/exclusion of folder(s)/file(s)/full path(s) |
---|
895 | %$ |
---|
896 | %$ assume this folder/file structure/contents |
---|
897 | %$ z:/abc/def/ghi/foo.m |
---|
898 | %$ z:/abc/def/ghi/foo.txt |
---|
899 | %$ z:/abc/def/ghi/goo.p |
---|
900 | %$ z:/abc/def/xxy/goo.p |
---|
901 | %$ z:/abc/def/xxy/goo.txt |
---|
902 | %$ assume this root folder when running GREP |
---|
903 | %$ z:/abc/def |
---|
904 | %$ assume the recursion flag [-r] is set |
---|
905 | %$ |
---|
906 | %$ -Id '/xx' |
---|
907 | %$ only searches in folder |
---|
908 | %$ z:/abc/def/xxy ... all files |
---|
909 | %$ -Id 'xx' |
---|
910 | %$ -If '\.t' (note regular expression for <.>) |
---|
911 | %$ ***or*** |
---|
912 | %$ -Ip 'y/g.*\.t' |
---|
913 | %$ only searches in folder/file |
---|
914 | %$ z:/abc/def/xxy/goo.txt |
---|
915 | %$ -Xd '(de)|(xx)' |
---|
916 | %$ does not search any folder/file |
---|
917 | %$ -Xd 'x' |
---|
918 | %$ only searches in folder |
---|
919 | %$ z:/abc/def/ghi ... all files |
---|
920 | %$ -Xd 'x' |
---|
921 | %$ -Xf 'txt' |
---|
922 | %$ only searches in folder/files |
---|
923 | %$ z:/abc/def/ghi/foo.m |
---|
924 | %$ z:/abc/def/ghi/goo.p |
---|
925 | %$ -Xd 'xxx' |
---|
926 | %$ -If 'foo' |
---|
927 | %$ ***or*** |
---|
928 | %$ -Ip 'ghi/fo' |
---|
929 | %$ only searches in folder/files |
---|
930 | %$ z:/abc/def/ghi/foo.m |
---|
931 | %$ z:/abc/def/ghi/foo.txt |
---|
932 | %$ |
---|
933 | %$ note |
---|
934 | %$ ALL folder separators are replaced by |
---|
935 | %$ unix-style </> for entry checks to |
---|
936 | %$ facilitate the use of regular expression |
---|
937 | %$ leading/trailing </>s are significant |
---|
938 | %$ inclusions and exclusions are ANDed, but single tokens |
---|
939 | %$ within an option are OREed for final results |
---|
940 | %$ multiple inclusions/exclusions may be |
---|
941 | %$ listed in any order |
---|
942 | %$ using <-Ip> and <-Xp> only may be significantly slower |
---|
943 | %$ compared to combinations of <-I[df]> and <-X[df]> |
---|
944 | %$ since folders are resolved sequentially in depth, <-Xd> |
---|
945 | %$ options will exclude any subfolder below the |
---|
946 | %$ excluded folder(s) |
---|
947 | %$ |
---|
948 | %$ PATTERN |
---|
949 | %$ --------------------------------------------------------------------------------- |
---|
950 | %$ 'p1' will search <p1> in each FILE |
---|
951 | %$ {'p1',...,'pn'} will search each <px> in each FILE |
---|
952 | %$ |
---|
953 | %$ note 'p1' cannot include white spaces |
---|
954 | %$ {'p1'} may include white spaces |
---|
955 | %$ <px> may be a regular expression [-R] |
---|
956 | %$ only one input type will be used at runtime |
---|
957 | %$ precedence: 1. -f / 2. -e / 3. PATTERN |
---|
958 | %$ |
---|
959 | %$ FILE |
---|
960 | %$ --------------------------------------------------------------------------------- |
---|
961 | %$ 'f1' will search in folder/file <f1> |
---|
962 | %$ {'f1',...,'fn'} will search in each folder/file <fx> |
---|
963 | %$ |
---|
964 | %$ folder/file(s) are determined/expanded according to these rules |
---|
965 | %$ |
---|
966 | %$ FILE folder file remark |
---|
967 | %$ ---------------------------------------------------------- |
---|
968 | %$ f*.x ./ f*.x uses current folder |
---|
969 | %$ /a/b /a/b/ *.* search all files in folder |
---|
970 | %$ /a/b/ /a/b/ *.* search all files in folder |
---|
971 | %$ /a/b/* /a/b/ *.* search all files in folder |
---|
972 | %$ /a/b/*.x /a/b/ *.x search all <.x> in folder |
---|
973 | %$ /a/b/f /a/b/ f*.* if <f> is NOT a folder |
---|
974 | %$ /a/b/f*.x /a/b/ f*.x |
---|
975 | %$ |
---|
976 | %$ note if recursive folder search is selected [-r], |
---|
977 | %$ file(s) will be searched in the root path and |
---|
978 | %$ its subfolder(s) |
---|
979 | %$ the recursion engine does NOT use <genpath> |
---|
980 | %$ use the <-I?> and <-X?> options to use wildcard |
---|
981 | %$ searches on folders/files |
---|
982 | %$ |
---|
983 | %$ output arguments |
---|
984 | %$ --------------------------------------------------------------------------------- |
---|
985 | %$ FL cell array with unique list of files with matching patterns |
---|
986 | %$ P structure with timing and result of the engines (for programmers) |
---|
987 | %$ see: <grep -f> for information about .fields |
---|
988 | %$___FORMAT___ |
---|
989 | |
---|
990 | %$___OUTPUT___ |
---|
991 | %$ SYNTAX |
---|
992 | %$ [FL,P] = grep(...) |
---|
993 | %$ |
---|
994 | %$ output arguments |
---|
995 | %$ --------------------------------------------------------------------------------- |
---|
996 | %$ FL cell array with unique list of files with matching patterns |
---|
997 | %$ P structure with timings and result of the engines (for programmers) |
---|
998 | %$ |
---|
999 | %$ P.fieldname: contents explanation |
---|
1000 | %$ --------------------------------------------------------------------------------- |
---|
1001 | %$ magic: 'GREP' magic id |
---|
1002 | %$ ver: char current GREP version |
---|
1003 | %$ mver: char current ML version |
---|
1004 | %$ rundate: char datestr(clock) |
---|
1005 | %$ runtime: [t1 t2 t3] runtimes [sec]: |
---|
1006 | %$ - t1: full time spent in grep |
---|
1007 | %$ - t2: engine for (sub)folder(s) |
---|
1008 | %$ - t3: engine for pattern matching |
---|
1009 | %$ opt: [struct] current options and input args |
---|
1010 | %$ msg: char error message(s) |
---|
1011 | %$ section_1: '===== FOLDERS =' FOLDER STATS |
---|
1012 | %$ nfolder: double nr of unique folder(s) found |
---|
1013 | %$ nxfolder: double nr of excluded (sub)folder(s) [-Id|Xd] |
---|
1014 | %$ nafolder: double nr of all (sub)folder(s) |
---|
1015 | %$ folder: {char} unique folder name(s) |
---|
1016 | %$ fenum: double enumerator of (sub)folder(s) in .folder |
---|
1017 | %$ - subfolder(s) keep the .fenum of their root |
---|
1018 | %$ mdepth: double max depth of subfolder(s) |
---|
1019 | %$ fdepth: double depth of each subfolder [0: root] |
---|
1020 | %$ section_2: '===== PATTERNS =' PATTERN STATS |
---|
1021 | %$ npat: double nr of patterns |
---|
1022 | %$ pattern: {char} pattern(s) |
---|
1023 | %$ porigin: char origin of pattern(s): |
---|
1024 | %$ - 'command line' |
---|
1025 | %$ - name of pattern file [-f] |
---|
1026 | %$ section_3: '===== FILES =' FILE STATS |
---|
1027 | %$ nfiles: double nr of files searched |
---|
1028 | %$ nxfiles: double nr of excluded file(s) [-If|Xf] |
---|
1029 | %$ nafiles: double nr of all file(s) after [-Id|Xd] |
---|
1030 | %$ nbytes: double nr of bytes read |
---|
1031 | %$ nlines: double nr of lines searched |
---|
1032 | %$ section_4: '===== MATCHES =' MATCH STATS |
---|
1033 | %$ mfiles: double nr of file(s) with matching patterns |
---|
1034 | %$ mbytes: double nr of bytes of .mfiles file(s) |
---|
1035 | %$ mlines: double nr of lines of .mfiles file(s) |
---|
1036 | %$ pfiles: double nr of .files with matching patterns |
---|
1037 | %$ pcount: double nr of lines with a match |
---|
1038 | %$ files: {char} file name for each match |
---|
1039 | %$ - repeated for each matching pattern |
---|
1040 | %$ lcount: [double] count of matching lines in .files [-c] |
---|
1041 | %$ findex: [double] index into .files for each match |
---|
1042 | %$ pindex: [double] index into .pattern for each match |
---|
1043 | %$ line: [double] nr of matching line |
---|
1044 | %$ match: {char} matching line |
---|
1045 | %$ result: [char] runtime output |
---|
1046 | %$ |
---|
1047 | %$ NOTE |
---|
1048 | %$ to reconstruct user defined results from P, which may be useful |
---|
1049 | %$ with the [-s] option, a programmer can use constructs like |
---|
1050 | %$ - file name|nr counts |
---|
1051 | %$ fmt=repmat(max(cellfun('length',P.files)),P.pfiles,1); |
---|
1052 | %$ r=[num2cell(fmt+3),... |
---|
1053 | %$ P.files,... |
---|
1054 | %$ num2cell(P.lcount)].'; |
---|
1055 | %$ s=sprintf('%-*s: %5d\n',r{:}) |
---|
1056 | %$ - file name|pattern|line nr|nr counts|matching line |
---|
1057 | %$ r=[P.files(P.findex),... |
---|
1058 | %$ P.pattern(P.pindex),... |
---|
1059 | %$ num2cell(P.line),... |
---|
1060 | %$ num2cell(P.lcount(P.findex)),... |
---|
1061 | %$ P.match] |
---|
1062 | %$___OUTPUT___ |
---|
1063 | |
---|
1064 | %$___EXAMPLE___ |
---|
1065 | % GREP EXAMPLES |
---|
1066 | % assume GREP.TXT is in your current working folder |
---|
1067 | fnam='grep.txt'; |
---|
1068 | % - show contents (note all spaces are TABs!) |
---|
1069 | type(fnam); |
---|
1070 | |
---|
1071 | % simple case insensitive [-i] string search in GREP.M for instances of |
---|
1072 | % Version |
---|
1073 | % listing file name [def] and the line number [-n] of occurrences |
---|
1074 | %------------------------------------------------------------------------------- |
---|
1075 | grep -i -n Version grep.m |
---|
1076 | |
---|
1077 | % regular expression search [-R] in GREP.M for instances of |
---|
1078 | % =true or =false |
---|
1079 | % listing line number [-n] but not the file name [-Q] |
---|
1080 | %------------------------------------------------------------------------------- |
---|
1081 | grep -Q -n -R =true|=false grep.m |
---|
1082 | |
---|
1083 | % simple string search in GREP.M for exactly matching [-x] instances of |
---|
1084 | % \t\tmsg=true; |
---|
1085 | % listing the file name [def] and the line number [-n] for each occurrence |
---|
1086 | %------------------------------------------------------------------------------- |
---|
1087 | TAB=sprintf('\t'); |
---|
1088 | fl=grep('-x -n',[TAB,TAB,'msg=true;'],'grep.m'); |
---|
1089 | |
---|
1090 | % simple string search in GREP.TXT for |
---|
1091 | % every line of itself in turn |
---|
1092 | % using the pattern-file [-f] option and |
---|
1093 | % listing the full file name and pattern for each file with matches [-l] |
---|
1094 | % as well as the file name [def] for each occurrence |
---|
1095 | %------------------------------------------------------------------------------- |
---|
1096 | fl=grep('-l -f',fnam,fnam); |
---|
1097 | |
---|
1098 | % simple string search in GREP.TXT for instances of |
---|
1099 | % -n |
---|
1100 | % using the [-e] option since -n itself is an option flag (listing line number!) |
---|
1101 | % and listing the file name [def] for each non-matching line [-v] only |
---|
1102 | % - compare with previous example! |
---|
1103 | %------------------------------------------------------------------------------- |
---|
1104 | fl=grep('-v -e',{'-n'},fnam); |
---|
1105 | |
---|
1106 | % full depth search [-r] of the entire ELFUN TOOLBOX for instances of |
---|
1107 | % sign or cosine or atan |
---|
1108 | % listing the full file name and pattern for each file with matches [-l] |
---|
1109 | % as well as the file name [def] and the line number [-n] for each occurrence |
---|
1110 | %------------------------------------------------------------------------------- |
---|
1111 | fpat=[matlabroot,'/toolbox/matlab/elfun']; |
---|
1112 | fl=grep('-r -l -n',{'sign','cosine','atan'},fpat); |
---|
1113 | |
---|
1114 | % full depth search [-r] of the entire ELFUN TOOLBOX for instances of |
---|
1115 | % sign or cosine or atan |
---|
1116 | % using the two versions of the [-e] option and |
---|
1117 | % listing the full file name and pattern for each file with matches [-l] |
---|
1118 | % as well as the count [-c] of all instances |
---|
1119 | %------------------------------------------------------------------------------- |
---|
1120 | fl=grep('-r -l -c -e sign -e',{'cosine','atan'},fpat); |
---|
1121 | |
---|
1122 | % full depth search [-r] of the entire ELFUN TOOLBOX for instances of |
---|
1123 | % sign or cosine or atan |
---|
1124 | % only including files with a regular expression pattern [-If] |
---|
1125 | % [Cc]ont |
---|
1126 | % using the two versions of the [-e] option and |
---|
1127 | % listing the full file name and pattern for each file with matches [-l] |
---|
1128 | % as well as the file name [def] and the line number [-n] for each occurrence |
---|
1129 | %------------------------------------------------------------------------------- |
---|
1130 | fl=grep('-r -l -n -If [Cc]ont -e sign -e',{'cosine','atan'},fpat); |
---|
1131 | |
---|
1132 | % full depth search [-r] of the entire ELFUN TOOLBOX for instances of |
---|
1133 | % sign or cosine or atan |
---|
1134 | % only including files with a regular expression pattern [-If] |
---|
1135 | % [Cc]ont |
---|
1136 | % and excluding folders with a pattern [-Xd] |
---|
1137 | % /ja |
---|
1138 | % - using the two versions of the [-e] option, |
---|
1139 | % and listing the full file name and pattern for each file with matches [-l] |
---|
1140 | % as well as the file name [def] and the line number [-n] for each occurrence |
---|
1141 | %------------------------------------------------------------------------------- |
---|
1142 | fl=grep('-r -l -n -If [Cc]ont -e sign -e',{'cosine','atan'},'-Xd','/ja',fpat); |
---|
1143 | %$___EXAMPLE___ |
---|
1144 | %--------------------------------------------------------------------------------- |
---|
1145 | %} |
---|