⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findfiles.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
📖 第 1 页 / 共 2 页
字号:
function [filesfound, numberfound] = findfiles(varargin)
% findfiles  - Linux/UNIX-like find command/function
%
% returns a list in which all files are listed that match one of the
% patterns.
%
% FORMAT:
% [files, number] = findfiles(startfolder, patterns, opts, ....)
%
% - startfolder     <char array> folder where to start search
% - patterns        <cell array <char array>> file patterns (shell-like)
%   (alt.)          <char array>  : single pattern
% - opt             <struct array>: optional parameters in the form of
%   .cellstr        <double array>: if set and !0 -> return as cellstr
%   .chararr        <double array>: if set and !0 -> return as char array
%   .depth          <double array>: sets both minimum and maximum depth
%   .dirs           <double array>: if set and !0 -> dirs instead of files
%   .filesize       <double array>: if set and !0 -> only matching files
%   .maxdepth       <double array>: maximum depth where to search
%   .mindepth       <double array>: minimum depth where to search
%   .maxage         <double array>: seconds file must have changed in
%   .minage         <double array>: seconds file must not have changed in
%   .oneperdir      <double array>: if set and !0 -> only first match
%   .relative       <... array>   : if set -> !0 -> './' // char array
%
% when used as a command, multiple opts can be given as multiple arguments,
% seperated by spaces (' '):
%
% findfiles /search/folder *mypattern*.txt depth=3 oneperdir=1 relative=./
%
% when used in functional context, a second return value, the number
% of matching files, can be obtained:
%
% [files,number] = findfiles('/where','*.txt');
%
% NOTE: the minage/maxage feature only fully works when the system
% returns English-style month in calls to dir. i.e. under Linux, set the
% LANG environmental setting to 'en_US' before starting up MatLab

% Version:  v0.7a
% Build:    7080813
% Date:     Aug-08 2007, 1:52 PM CEST
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

%
% TODO: make the returning object (cell) a persistent value to increase
%       speed by not having to return it from recursive calls !!!
%

% enough arguments ?
if nargin < 1
    error( ...
        'BVQXtools:TooFewArguments',...
        'Too few arguments. Try ''help %s''.',...
        mfilename ...
    );
end
if nargin == 1
    varargin{2} = varargin{1};
    varargin{1} = pwd;
end

% shortcut variable
fsep = filesep;

% sanity checks: startfolder
startfolder = varargin{1};
if ischar(startfolder) && ...
   ~isempty(startfolder)

    % does startfolder contain an asterisk?
    if any(startfolder == '?' | startfolder == '*')

        % then put startfolder into a cell array to treat this case
        [filesfound, numberfound] = findfiles({startfolder}, varargin{2:end});
        return;
    end

% startfolder is a list of folders
elseif iscell(startfolder) && ...
   ~isempty(startfolder)

    % generate expanded list
    nstartfolder = cell(0);

    % iterate over items
    for nelem = 1:numel(startfolder)

        % must be non-empty char
        if ~ischar(startfolder{nelem}) || ...
            isempty(startfolder{nelem})
            error( ...
                'BVQXtools:BadArgument',...
                'Bad startfolder argument.' ...
            );
        end

        % expand pattern?
        if ~any(startfolder{nelem} == '?' | startfolder{nelem} == '*')

            % put into final list
            nstartfolder{end+1} = startfolder{nelem};

        % or look up matching folders
        else

            % split along possible path separators
            [pparts, cparts] = splittocell(startfolder{nelem}, '/\', 1, 1);
            if any('/\:' == startfolder{nelem}(1))
                pparts = [{''}, pparts];
                cparts = cparts + 1;
            end

            % look for first pattern
            for cpart = 1:cparts
                if any(pparts{cpart} == '?' | pparts{cpart} == '*')
                    break;
                end
            end

            % if the pattern occurs in first part, look in current dir
            if cpart==1
                [pfolders, npfolders] = findfiles('.', ...
                    pparts{1}, ...
                    struct('dirs', 1, 'depth', 1));

            % otherwise glue first parts together and look up matches
            else
                [pfolders, npfolders] = findfiles( ...
                    gluetostring({pparts{1:(cpart-1)}},fsep), ...
                    pparts{cpart}, ...
                    struct('dirs', 1, 'depth', 1));
            end

            % the pattern was not in last part
            if cpart < cparts

                % put remaining parts back on
                for ppart = 1:npfolders
                    pfolders{ppart} = [pfolders{ppart} fsep ...
                        gluetostring({pparts{(cpart+1):end}},fsep)];
                end
            end

            % put results at end of list
            nstartfolder = [nstartfolder, pfolders];
        end
    end

    % we start with no files found
    filesfound = cell(0);

    % for each folder in list
    for nelem = 1:length(nstartfolder)

        % if there (iteratively) remains a pattern char, redo this
        if any(nstartfolder{nelem} == '?' | nstartfolder{nelem} == '*')
            filesfound = [filesfound(1:end); ...
                findfiles({nstartfolder{nelem}}, varargin{2:end})];

        % otherwise get files in this folder and put at end of array
        elseif exist(nstartfolder{nelem}, 'dir') == 7
            filesfound = [filesfound(1:end); ...
                findfiles(nstartfolder{nelem}, varargin{2:end})];
        end
    end

    % report the total number found
    numberfound = length(filesfound);
    return;

% illegal first argument
else
    error( ...
        'BVQXtools:BadArgument',...
        'Bad startfolder argument.'...
    );
end

% we're now going for the single folder case and startfolder is OK

% append missing fsep if needed
if startfolder(end) ~= fsep
    startfolder = [startfolder fsep];
end

% startfolder exists?
if exist(startfolder,'dir') ~= 7
    error( ...
        'BVQXtools:FolderNotFound',...
        'Startfolder (%s) not found or no folder.',...
        strrep(startfolder,'\','\\') ...
    );
end

% - sanity checks patterns
patterns = varargin{2};

% default is cell, otherwise
if ~iscell(patterns)

    % if is character, put into cell
    if ischar(patterns)
        patterns = { patterns };

    % otherwise bail out
    else
        error( ...
            'BVQXtools:BadArgument', ...
            'Patterns must either be a single string or a cell array!' ...
        );
    end
end

% check each pattern
for count = 1:size(patterns,2)

    % only accept chars
    if ~ischar(patterns{count}) || ...
       ~any(patterns{count} == '?' | patterns{count} == '*')
        error( ...
            'BVQXtools:BadArgument', ...
            'All patterns cell contents must be char patterns!' ...
        );
    end
end

% option argument parsing, default options
if nargin < 3
    opt.dirs = 0;
    opt.filesize = 0;
    opt.maxdepth = 0;
    opt.mindepth = 0;
    opt.maxage = -1;
    opt.minage = -1;
    opt.oneperdir = 0;
    opt.relative = 0;
    opt.return = 'cellarr';
    opt.rfolder = startfolder;

% parse options
else
    opt = varargin{3};

    % non-struct options
    if ~isstruct(opt)

        % yet start with default struct
        clear opt;
        opt.dirs = 0;
        opt.filesize = 0;
        opt.maxdepth = 0;
        opt.mindepth = 0;
        opt.maxage = -1;
        opt.minage = -1;
        opt.oneperdir = 0;
        opt.relative = 0;
        opt.return = 'cellarr';
        opt.rfolder = startfolder;

        % parse all arguments
        for acount=3:nargin

            % char option
            if ischar(varargin{acount})

                % get argument name
                argnv = splittocell(varargin{acount}, '=', 1);
                oname = argnv{1};

                % and possible option value
                if size(argnv,2) > 1
                    oval = argnv{2};
                else
                    oval = '';
                end

                % only accept known arguments
                switch lower(oname)

                    % option: cellstr, set return type
                    case {'cellstr'}
                        oval = str2double(oval);
                        if oval ~= 0
                            opt.return = 'cellstr';
                        end

                    % option: chararr, set return type
                    case {'chararr'}
                        oval = str2double(oval);
                        if oval ~= 0
                            opt.return = 'chararr';
                        end

                    % option: depth (min and max)
                    case {'depth'}
                        if str2double(oval) >= 0
                            opt.maxdepth = str2double(oval);
                            opt.mindepth = str2double(oval);
                        else
                            opt.maxdepth=0;
                            opt.mindepth=0;
                        end

                    % option: dirs, set lookup type
                    case {'dirs'}
                        oval = str2double(oval);
                        if oval == 0
                            opt.dirs = 0;
                        else
                            opt.dirs = 1;
                        end

                    % option: filesize
                    case {'filesize'}
                        if str2double(oval) >= 0
                            opt.filesize = fix(str2double(oval));
                        else
                            opt.filesize = 0;
                        end

                    % option: maxdepth
                    case {'maxdepth'}
                        if str2double(oval) >= 0
                            opt.maxdepth = fix(str2double(oval));
                        else
                            opt.maxdepth = 0;
                        end

                    % option: mindepth
                    case {'mindepth'}
                        if str2double(oval) >= 0
                            opt.mindepth = fix(str2double(oval));
                        else
                            opt.mindepth = 0;
                        end

                    % option: maxage
                    case {'maxage'}
                        if str2double(oval) >= 0
                            opt.maxage = fix(str2double(oval));
                        else
                            opt.maxage = -1;
                        end

                    % option: minage
                    case {'minage'}
                        if str2double(oval) >= 0
                            opt.minage = fix(str2double(oval));
                        else
                            opt.minage = -1;
                        end

                    % option: oneperdir
                    case {'oneperdir'}
                        oval = str2double(oval);
                        if oval == 0
                            opt.oneperdir = 0;
                        else
                            opt.oneperdir = 1;
                        end

                    % option: relative
                    case 'relative'
                        noval = str2double(oval);
                        if ~isnan(noval)
                            opt.relative = noval;
                            if noval < 1
                                opt.rfolder = startfolder;
                            else
                                opt.rfolder = ['.' fsep];
                            end
                        else
                            opt.relative = 1;
                            opt.rfolder = oval;
                        end;
                end
            end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -