如何在MATLAB中的特定目录下获取所有文件?


102

我需要获取所有这些文件,D:\dic并将它们循环遍历以分别进行进一步处理。

MATLAB是否支持这种操作?

可以在其他脚本中完成,例如PHP,Python ...

Answers:


130

更新:鉴于这篇文章已经很老了,并且在此期间我已经对该实用程序进行了很多修改以供自己使用,所以我认为我应该发布一个新版本。我的最新代码可以在MathWorks File Exchange上找到:dirPlus.m。您也可以从GitHub获取源代码。

我做了一些改进。现在,它为您提供了添加完整路径或仅返回文件名(由DoresoomOz Radiano合并)以及将正​​则表达式模式应用于文件名(由Peter D合并)的选项。另外,我还添加了对每个文件应用验证功能的功能,使您可以根据标准(而不是文件名,文件大小,内容,创建日期等)选择文件。


注意:在较新版本的MATLAB(R2016b和更高版本)中,该dir函数具有递归搜索功能!因此,您可以执行以下操作以获取*.m当前文件夹的所有子文件夹中所有文件的列表:

dirData = dir('**/*.m');

旧代码:(用于后代)

这是一个函数,它以递归方式搜索给定目录的所有子目录,并收集找到的所有文件名的列表:

function fileList = getAllFiles(dirName)

  dirData = dir(dirName);      %# Get the data for the current directory
  dirIndex = [dirData.isdir];  %# Find the index for directories
  fileList = {dirData(~dirIndex).name}';  %'# Get a list of the files
  if ~isempty(fileList)
    fileList = cellfun(@(x) fullfile(dirName,x),...  %# Prepend path to files
                       fileList,'UniformOutput',false);
  end
  subDirs = {dirData(dirIndex).name};  %# Get a list of the subdirectories
  validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
                                               %#   that are not '.' or '..'
  for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dirName,subDirs{iDir});    %# Get the subdirectory path
    fileList = [fileList; getAllFiles(nextDir)];  %# Recursively call getAllFiles
  end

end

将以上函数保存在MATLAB路径中的某个位置后,可以通过以下方式调用它:

fileList = getAllFiles('D:\dic');

3
+1-很好的解决方案。我不知道是否有必要,但是如果您插入以下行:fileList = cellfun(@(x)strcat([dirName,'\'],x),fileList,'UniformOutput',0); 在您的第一个fileList定义和subDirs定义之间的解决方案中,它将返回每个文件的完整路径和文件名。
Doresoom 2010年

2
@Doresoom:很好的建议,尽管我改用FULLFILE,因为它可以为您处理文件分隔符的选择(在UNIX和Windows中是不同的)。同样,您可以这样做,fileList = strcat(dirName,filesep,fileList);而不是使用CELLFUN,尽管这样可能会导致不必要的文件分隔符,而FULLFILE也可以帮您解决。
gnovice 2010年

2
@ gnovice,@ Doreseoom-根据mathworks.com/access/helpdesk/help/techdoc/ref/dir.html,“ dir”返回的顺序取决于操作系统。我不确定,例如,如果将DOS DIRCMD变量设置为更改顺序的内容,会发生什么。Octave可以正常处理(。和..仍然是第一位),但是我没有MATLAB可以测试。
mtrw

2
@gnovice:这超出了OP的范围,但是我发现将正则表达式内置到函数中很有用。 if ~isempty(fileList) fileList = cellfun(@(x) fullfile(dirName,x),... %# Prepend path to files fileList,'UniformOutput',false); matchstart = regexp(fileList, pattern); fileList = fileList(~cellfun(@isempty, matchstart)); end 并将功能签名更改为getAllFiles(dirName, pattern)(也在第二行至最后一行)
Peter D

1
好答案,谢谢!我已经阐述了代码,支持2个额外的参数- stackoverflow.com/a/26449095/69555
奥兹Radiano

25

您正在寻找dir返回目录内容。

要循环显示结果,只需执行以下操作:

dirlist = dir('.');
for i = 1:length(dirlist)
    dirlist(i)
end

这应该为您提供以下格式的输出,例如:

name: 'my_file'
date: '01-Jan-2010 12:00:00'
bytes: 56
isdir: 0
datenum: []

您可以使它递归搜索包括子目录中的文件,但不包括目录本身吗?
Gtker

不关我的头顶,没有(我再也不用Matlab的定期访问),但是这可以帮助你:mathworks.com/matlabcentral/fileexchange/...
詹姆斯乙

2
如何排除...
Gtker

5
@Runner:排除。和..,删除dir输出中的前两个条目。或者,如果您要查找特定的文件类型,请运行dir('*.ext'),它会自动排除目录(当然,除非它们以.ext结尾)
Jonas 2010年

14

我使用了这个好答案中提到的代码,并将其扩展为支持我在本例中需要的2个其他参数。参数是要过滤的文件扩展名,以及指示是否将完整路径连接到文件名的标志。

我希望它已经足够清楚,有人会发现它是有益的。

function fileList = getAllFiles(dirName, fileExtension, appendFullPath)

  dirData = dir([dirName '/' fileExtension]);      %# Get the data for the current directory
  dirWithSubFolders = dir(dirName);
  dirIndex = [dirWithSubFolders.isdir];  %# Find the index for directories
  fileList = {dirData.name}';  %'# Get a list of the files
  if ~isempty(fileList)
    if appendFullPath
      fileList = cellfun(@(x) fullfile(dirName,x),...  %# Prepend path to files
                       fileList,'UniformOutput',false);
    end
  end
  subDirs = {dirWithSubFolders(dirIndex).name};  %# Get a list of the subdirectories
  validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
                                               %#   that are not '.' or '..'
  for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dirName,subDirs{iDir});    %# Get the subdirectory path
    fileList = [fileList; getAllFiles(nextDir, fileExtension, appendFullPath)];  %# Recursively call getAllFiles
  end

end

运行代码的示例:

fileList = getAllFiles(dirName, '*.xml', 0); %#0 is false obviously

8

您可以使用regexp或strcmp消除... 或者isdir如果只希望目录中的文件而不是文件夹中的文件,则可以使用该字段。

list=dir(pwd);  %get info of files/folders in current directory
isfile=~[list.isdir]; %determine index of files vs folders
filenames={list(isfile).name}; %create cell array of file names

或合并最后两行:

filenames={list(~[list.isdir]).name};

有关目录中不包含的文件夹列表。和..

dirnames={list([list.isdir]).name};
dirnames=dirnames(~(strcmp('.',dirnames)|strcmp('..',dirnames)));

从这一点开始,您应该能够将代码放入嵌套的for循环中,并继续搜索每个子文件夹,直到您的目录名返回每个子目录的空单元格为止。


@Runner:如果您使用了一些for和while循环,它确实可以...但是我现在很懒惰地实现它。
Doresoom 2010年

尽管+1并不能完全回答问题,但它确实提供了一种快速清除目录的方法。
jhfrontz 2012年

7

这个答案并不能直接回答问题,但可能是一个很好的解决方案。

我支持gnovice的解决方案,但想提供另一种解决方案:使用操作系统的系统相关命令:

tic
asdfList = getAllFiles('../TIMIT_FULL/train');
toc
% Elapsed time is 19.066170 seconds.

tic
[status,cmdout] = system('find ../TIMIT_FULL/train/ -iname "*.wav"');
C = strsplit(strtrim(cmdout));
toc
% Elapsed time is 0.603163 seconds.

正:

  • 非常快(在我的情况下,是Linux上18000个文件的数据库)。
  • 您可以使用经过良好测试的解决方案。
  • 您无需学习或重新发明新的语法即可选择*.wav文件。

负:

  • 您不是系统独立的。
  • 您依赖于可能难以解析的单个字符串。

3

我不知道单功能方法,但是您只能使用它genpath来递归子目录列表。该列表以分号分隔的目录字符串形式返回,因此您必须使用strread将其分开,即

dirlist = strread(genpath('/path/of/directory'),'%s','delimiter',';')

如果您不想包括给定目录,请删除的第一个条目dirlist,即dirlist(1)=[];因为它始终是第一个条目。

然后使用循环号获取每个目录中的文件列表dir

filenamelist=[];
for d=1:length(dirlist)
    % keep only filenames
    filelist=dir(dirlist{d});
    filelist={filelist.name};

    % remove '.' and '..' entries
    filelist([strmatch('.',filelist,'exact');strmatch('..',filelist,'exact'))=[];
    % or to ignore all hidden files, use filelist(strmatch('.',filelist))=[];

    % prepend directory name to each filename entry, separated by filesep*
    for f=1:length(filelist)
        filelist{f}=[dirlist{d} filesep filelist{f}];
    end

    filenamelist=[filenamelist filelist];
end

filesep 返回运行MATLAB的平台的目录分隔符。

这为您提供了单元格数组filenamelist中具有完整路径的文件名列表。我知道,这不是最巧妙的解决方案。


出于性能原因,我不想genpath搜索它,它实际上搜索了两次。
Gtker

2
使用GENPATH的一个缺点是,它将仅包含MATLAB路径中允许的子目录。例如,如果您有名为的目录private,则将不包含这些目录。
gnovice

1

这是一个方便的功能,用于.mat在根文件夹中获取具有指定格式(通常为)的文件名!

    function filenames = getFilenames(rootDir, format)
        % Get filenames with specified `format` in given `foler` 
        %
        % Parameters
        % ----------
        % - rootDir: char vector
        %   Target folder
        % - format: char vector = 'mat'
        %   File foramt

        % default values
        if ~exist('format', 'var')
            format = 'mat';
        end

        format = ['*.', format];
        filenames = dir(fullfile(rootDir, format));
        filenames = arrayfun(...
            @(x) fullfile(x.folder, x.name), ...
            filenames, ...
            'UniformOutput', false ...
        );
    end

您可以使用以下代码段:)

filenames = getFilenames('D:/dic/**');
for i = 1:numel(filenames)
    filename = filenames{i};
    % do your job!
end

0

几乎没有修改,但几乎采用类似的方法来获取每个子文件夹的完整文件路径

dataFolderPath = 'UCR_TS_Archive_2015/';

dirData = dir(dataFolderPath);      %# Get the data for the current directory
dirIndex = [dirData.isdir];  %# Find the index for directories
fileList = {dirData(~dirIndex).name}';  %'# Get a list of the files
if ~isempty(fileList)
    fileList = cellfun(@(x) fullfile(dataFolderPath,x),...  %# Prepend path to files
        fileList,'UniformOutput',false);
end
subDirs = {dirData(dirIndex).name};  %# Get a list of the subdirectories
validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
%#   that are not '.' or '..'
for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dataFolderPath,subDirs{iDir});    %# Get the subdirectory path
    getAllFiles = dir(nextDir);
    for k = 1:1:size(getAllFiles,1)
        validFileIndex = ~ismember(getAllFiles(k,1).name,{'.','..'});
        if(validFileIndex)
            filePathComplete = fullfile(nextDir,getAllFiles(k,1).name);
            fprintf('The Complete File Path: %s\n', filePathComplete);
        end
    end
end  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.