web-dev-qa-db-fra.com

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

Je dois obtenir tous ces fichiers sous D:\dic et les relier pour les traiter individuellement.

MATLAB supporte-t-il ce type d'opérations?

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

91
Gtker

Mise à jour: Étant donné que ce message est assez ancien et que j'ai beaucoup modifié cet utilitaire pour mon usage personnel au cours de cette période, j'ai décidé de poster une nouvelle version. Mon code le plus récent peut être trouvé sur L'échange de fichiers MathWorks : dirPlus.m . Vous pouvez également obtenir le code source depuis GitHub .

J'ai apporté un certain nombre d'améliorations. Il vous donne maintenant des options pour ajouter le chemin complet ou renvoyer uniquement le nom du fichier (incorporé à partir de Doresoom et Oz Radiano ) et appliquer un motif d’expression régulière aux noms de fichier (incorporé à partir de Peter D ). En outre, j’ai ajouté la possibilité d’appliquer une fonction de validation à chaque fichier, vous permettant ainsi de les sélectionner en fonction de critères autres que leur nom (taille du fichier, contenu, date de création, etc.).


REMARQUE: Dans les versions plus récentes de MATLAB (version R2016b et ultérieure), la fonction dir dispose de fonctionnalités de recherche récursive! Vous pouvez ainsi obtenir la liste de tous les fichiers *.m de tous les sous-dossiers du dossier actuel:

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

Ancien code: (pour la postérité)

Voici une fonction qui effectue une recherche récursive 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 sur votre chemin MATLAB, vous pouvez l’appeler de la manière suivante:

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

Vous recherchez dir pour renvoyer le contenu du répertoire.

Pour faire une boucle sur les résultats, vous pouvez simplement procéder comme suit:

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

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

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

J'ai utilisé le code mentionné dans cette excellente réponse et l'ai développé pour prendre en charge deux paramètres supplémentaires dont j'avais besoin dans mon cas. Les paramètres sont des extensions de fichier à filtrer et un drapeau indiquant s'il faut concaténer le chemin complet du nom du fichier ou non.

J'espère que c'est assez clair et que quelqu'un le trouvera bénéfique.

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

Exemple pour exécuter le code:

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

Vous pouvez utiliser regexp ou strcmp pour éliminer . et .. Vous pouvez également utiliser le champ isdir si vous souhaitez uniquement des fichiers dans le répertoire, pas 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 une liste des dossiers du répertoire à l’exclusion. et ..

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

À partir de ce moment, vous devriez pouvoir insérer le code dans une boucle imbriquée et poursuivre la recherche dans chaque sous-dossier jusqu'à ce que vos noms de répertoire renvoient une cellule vide pour chaque sous-répertoire.

8
Doresoom

Cette réponse ne répond pas directement à la question mais peut être une bonne solution en dehors de la boîte.

J'ai voté pour la solution de gnovice, mais souhaitais 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 sur linux).
  • Vous pouvez utiliser des solutions bien testées.
  • Vous n'avez pas besoin d'apprendre ou de réinventer une nouvelle syntaxe pour sélectionner des fichiers i.e. *.wav.

Négatif:

  • Vous n'êtes pas indépendant du système.
  • Vous comptez sur une seule chaîne qui peut être difficile à analyser.
7
Lukas

Je ne connais pas de méthode à fonction unique pour cela, mais vous pouvez utiliser genpath pour réciférer une liste de sous-répertoires uniquement. Cette liste est renvoyée sous forme de chaîne de répertoires délimitée par des points-virgules. Vous devez donc la séparer à l'aide de strread, c'est-à-dire.

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

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

Ensuite, obtenez la liste des fichiers dans chaque répertoire avec un dir en boucle.

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 de 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. Pas la solution la plus soignée, je sais.

3
JS Ng

C'est une fonction pratique pour obtenir les noms de fichiers, avec le format spécifié (généralement .mat) dans un dossier racine!

    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

Dans votre cas, vous pouvez utiliser l'extrait suivant :)

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

Avec peu de modifications mais une approche presque similaire pour obtenir le chemin complet du fichier de chaque sous-dossier

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  
0
Spandan