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

Gtk*_*ker 97 directory recursion file-io matlab file

我需要获取所有这些文件D:\dic并循环它们以进一步单独处理.

MATLAB是否支持这种操作?

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

gno*_*ice 126

更新:鉴于这篇文章相当陈旧,我在这段时间内为自己的用途修改了这个实用程序,我想我应该发布一个新版本.我的最新代码可以在The MathWorks File Exchange上找到:dirPlus.m.您也可以从GitHub获取源代码.

我做了很多改进.它现在为您提供了前置完整路径或仅返回文件名(从DoresoomOz Radiano合并)的选项,并将正则表达式模式应用于文件名(由Peter D合并).此外,我添加了将验证功能应用于每个文件的功能,允许您根据标准以外的条件(即文件大小,内容,创建日期等)选择它们.


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

dirData = dir('**/*.m');
Run Code Online (Sandbox Code Playgroud)

旧代码:(后代)

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

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
Run Code Online (Sandbox Code Playgroud)

在MATLAB路径的某处保存上述函数后,可以通过以下方式调用它:

fileList = getAllFiles('D:\dic');
Run Code Online (Sandbox Code Playgroud)

  • +1 - 很棒的解决方案.我不知道是否有必要,但如果你插入行:fileList = cellfun(@(x)strcat([dirName,'\'],x),fileList,'UniformOutput',0); 在第一个fileList定义和subDirs定义之间的解决方案中,它将返回每个文件的完整路径和文件名. (3认同)
  • @Doresoom:很好的建议,虽然我选择使用FULLFILE,因为它为你处理文件分隔符的选择(在UNIX和Windows上是不同的).另外,你可以做`fileList = strcat(dirName,filesep,fileList);`而不是使用CELLFUN,虽然你最终可以得到额外的不必要的文件分隔符,FULLFILE也会为你处理. (2认同)
  • @gnovice,@ Doreseoom - 根据http://www.mathworks.com/access/helpdesk/help/techdoc/ref/dir.html,'dir'返回的顺序取决于操作系统.我不确定如果你将DOS DIRCMD变量设置为改变顺序的东西会发生什么.Octave处理它确定(.和..仍然是第一个)但我没有MATLAB来测试. (2认同)
  • @gnovice:这超出了OP的问题,但我发现在函数中构建正则表达式很有用.`if~isempty(fileList)fileList = cellfun(@(x)fullfile(dirName,x),...%#前缀文件路径fileList,'UniformOutput',false); matchstart = regexp(fileList,pattern); fileList = fileList(~cellfun(@isempty,matchstart)); 结束`并将函数签名更改为`getAllFiles(dirName,pattern)`(也在第2行到最后一行) (2认同)

Jam*_*s B 25

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

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

dirlist = dir('.');
for i = 1:length(dirlist)
    dirlist(i)
end
Run Code Online (Sandbox Code Playgroud)

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

name: 'my_file'
date: '01-Jan-2010 12:00:00'
bytes: 56
isdir: 0
datenum: []
Run Code Online (Sandbox Code Playgroud)

  • @Runner:要排除.和..,删除dir输出中的前两个条目.或者,如果您正在寻找特定的文件类型,请运行`dir('*.ext')`,它会自动排除目录(当然,除非它们以.ext结尾) (5认同)
  • 如何排除`.`和`..`? (2认同)

Oz *_*ano 13

我使用了这个伟大答案中提到的代码并将其扩展为支持我需要的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
Run Code Online (Sandbox Code Playgroud)

运行代码的示例:

fileList = getAllFiles(dirName, '*.xml', 0); %#0 is false obviously
Run Code Online (Sandbox Code Playgroud)


Dor*_*oom 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
Run Code Online (Sandbox Code Playgroud)

或结合最后两行:

filenames={list(~[list.isdir]).name};
Run Code Online (Sandbox Code Playgroud)

对于目录中的文件夹列表,不包括.和..

dirnames={list([list.isdir]).name};
dirnames=dirnames(~(strcmp('.',dirnames)|strcmp('..',dirnames)));
Run Code Online (Sandbox Code Playgroud)

从这一点开始,您应该能够在嵌套的for循环中抛出代码,并继续搜索每个子文件夹,直到您的dirnames为每个子目录返回一个空单元格.


Luk*_*kas 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.
Run Code Online (Sandbox Code Playgroud)

正:

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

负:

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