102 votes

Comment obtenir tous les fichiers sous un répertoire spécifique dans MATLAB ?

J'ai besoin de mettre tous ces fichiers sous D:\dic et les passer en boucle pour les traiter individuellement.

MATLAB prend-il en charge ce type d'opérations ?

Cela peut être fait dans d'autres scripts comme PHP, Python...

130voto

gnovice Points 70970

Mise à jour : Étant donné que ce post est assez ancien, et que j'ai beaucoup modifié cet utilitaire pour mon propre usage pendant ce temps, j'ai pensé que je devais poster une nouvelle version. Mon code le plus récent peut être trouvé sur The MathWorks File Exchange : dirPlus.m . Vous pouvez également obtenir la source à partir de GitHub .

J'ai apporté un certain nombre d'améliorations. Il vous donne maintenant la possibilité de faire précéder le chemin d'accès complet ou de renvoyer uniquement le nom du fichier (incorporé à partir de Doresoom et Oz Radiano ) et appliquer un modèle d'expression régulière aux noms de fichiers (incorporé à partir de Peter D ). En outre, j'ai ajouté la possibilité d'appliquer une fonction de validation à chaque fichier, ce qui vous permet de les sélectionner sur la base de critères autres que leur simple nom (c'est-à-dire la taille du fichier, son contenu, sa date de création, etc.)


NOTE : Dans les versions plus récentes de MATLAB (R2016b et ultérieures), la fonction dir a des capacités de recherche récursive ! Ainsi, vous pouvez faire ceci pour obtenir une liste de tous les éléments suivants *.m les fichiers de tous les sous-dossiers du dossier actuel :

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

Ancien code : (pour la postérité)

Voici une fonction qui recherche récursivement dans tous les sous-répertoires d'un répertoire donné, en collectant une liste de tous les noms de fichiers qu'elle trouve :

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

Après avoir enregistré la fonction ci-dessus quelque part dans votre chemin MATLAB, vous pouvez l'appeler de la manière suivante :

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

0 votes

Comment faire pour qu'il renvoie le chemin complet au lieu des seuls noms de fichiers ?

3 votes

+1 - Excellente solution. Je ne sais pas si c'est nécessaire, mais si vous insérez la ligne : fileList = cellfun(@(x) strcat([dirName, '\'],x),fileList, 'UniformOutput',0) ; dans votre solution entre la première définition de fileList et la définition des subDirs, cela retournera le chemin complet et le nom de fichier pour chaque fichier.

2 votes

@Doresoom : Bonne suggestion, même si j'ai préféré utiliser FULLFILE, car il gère le choix du séparateur de fichiers pour vous (qui est différent sous UNIX et Windows). Aussi, vous pourriez simplement faire fileList = strcat(dirName,filesep,fileList); au lieu d'utiliser CELLFUN, bien que vous puissiez vous retrouver avec des séparateurs de fichiers supplémentaires inutiles de cette façon, ce dont FULLFILE s'occupe également pour vous.

25voto

James Burgess Points 4616

Vous êtes à la recherche de dir pour retourner le contenu du répertoire.

Pour boucler sur les résultats, vous pouvez simplement faire ce qui suit :

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

Cela devrait vous donner une sortie au format suivant, par exemple :

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

0 votes

Pouvez-vous faire en sorte que la recherche soit récursive, incluant les fichiers des sous-répertoires mais excluant le répertoire lui-même ?

0 votes

Non, pas de mémoire, non (je n'ai plus un accès régulier à Matlab), mais ceci peut vous aider : mathworks.com/matlabcentral/fileexchange/

2 votes

Comment exclure . et .. ?

8voto

Doresoom Points 4081

Vous pouvez utiliser regexp ou strcmp pour éliminer . et .. Ou vous pouvez utiliser le isdir si vous ne voulez que des fichiers dans le répertoire, et non des dossiers.

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

ou combinez les deux dernières lignes :

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

Pour obtenir la liste des dossiers du répertoire à l'exclusion de . et .

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

À partir de là, vous devriez pouvoir lancer le code dans une boucle for imbriquée, et continuer à chercher chaque sous-dossier jusqu'à ce que votre dirnames renvoie une cellule vide pour chaque sous-répertoire.

0 votes

@Runner : C'est possible si vous utilisez des boucles for et while... mais j'ai la flemme de le faire maintenant.

0 votes

+1 même si cela ne répond pas exactement à la question, cela fournit un moyen d'éliminer rapidement les répertoires.

7voto

Lukas Points 179

Cette réponse ne répond pas directement à la question mais peut être une bonne solution en dehors des sentiers battus.

J'ai voté en faveur de la solution de gnovice, mais je souhaite proposer une autre solution : Utilisez la commande dépendante du système de votre système d'exploitation :

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.

Positif :

  • Très rapide (dans mon cas pour une base de données de 18000 fichiers sous linux).
  • Vous pouvez utiliser des solutions éprouvées.
  • Vous n'avez pas besoin d'apprendre ou de réinventer une nouvelle syntaxe pour sélectionner par exemple. *.wav des fichiers.

Négatif :

  • Vous n'êtes pas indépendant du système.
  • Vous vous appuyez sur une seule chaîne de caractères qui peut être difficile à analyser.

3voto

JS Ng Points 559

Je ne connais pas de méthode à fonction unique pour cela, mais vous pouvez utiliser genpath pour récuser une liste de uniquement les sous-répertoires . Cette liste est retournée sous la forme d'une chaîne de répertoires délimitée par des points-virgules, vous devrez donc la séparer en utilisant strread, c'est-à-dire

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

Si vous ne voulez pas inclure le répertoire donné, supprimez la première entrée de la commande dirlist c'est-à-dire dirlist(1)=[]; puisqu'il s'agit toujours de la première entrée.

Puis obtenir la liste des fichiers dans chaque répertoire avec une boucle 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 renvoie le séparateur de répertoire pour la plate-forme sur laquelle MATLAB est exécuté.

Cela vous donne une liste de noms de fichiers avec des chemins complets dans le tableau de cellules. filenamelist . Ce n'est pas la meilleure solution, je sais.

0 votes

Pour des raisons de performance, je ne veux pas genpath ,il cherche essentiellement deux fois.

2 votes

L'un des inconvénients de l'utilisation de GENPATH est qu'il n'inclut que les sous-répertoires autorisés dans le chemin d'accès à MATLAB. Par exemple, si vous avez des répertoires nommés private ils ne seront pas inclus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X