Soru MATLAB'de belirli bir dizinin altındaki tüm dosyalar nasıl alınır?


Tüm bu dosyaları almam gerek D:\dic ve ayrı ayrı işlemek için onlara döngü.

MATLAB bu tür operasyonları destekliyor mu?

PHP, Python gibi diğer betiklerde yapılabilir ...


89
2018-04-16 11:49


Menşei




Cevaplar:


Güncelleştirme: Bu gönderinin oldukça eski olduğunu ve bu kullanım sırasında kendi kullanımım için çok fazla değişiklik yaptığımı düşündüğümde, yeni bir sürüm yüklemem gerektiğini düşündüm. En yeni kodum şu adreste bulunabilir: MathWorks Dosya Değişimi: dirPlus.m. Kaynağı da alabilirsiniz. GitHub.

Bir dizi iyileştirme yaptım. Artık tam yolun başına ya da yalnızca dosya adını döndürmek için seçenekler sunar. Doresoom ve Oz Radiano) ve dosya adlarına düzenli bir ifade kalıbı uygulayın ( Peter D). Buna ek olarak, her dosyaya bir doğrulama işlevi uygulama yeteneğini ekledim ve bunları yalnızca isimleri (yani dosya boyutu, içerik, oluşturma tarihi, vb.) Dışındaki ölçütlere göre seçebilmenizi sağladım.


NOT: MATLAB'ın (R2016b ve üstü) daha yeni sürümlerinde, dir işlev, özyinelemeli arama yeteneklerine sahiptir! Yani hepsini listelemek için bunu yapabilirsin *.m geçerli klasörün tüm alt klasörlerinde bulunan dosyalar:

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

Eski kod: (kuşak için)

İşte, belirli bir dizinin tüm alt dizinleri boyunca yinelemeli olarak arama yapan ve bulduğu tüm dosya adlarının bir listesini toplayan bir işlevdir:

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

Yukarıdaki işlevi MATLAB yolunuzda bir yere kaydettikten sonra, aşağıdaki şekilde çağırabilirsiniz:

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

124
2018-04-16 16:06



+1 - Harika çözüm. Gerekli olup olmadığını bilmiyorum, ancak satırı eklerseniz: fileList = cellfun (@ (x) strcat ([dirName, '\'], x), fileList, 'UniformOutput', 0); ilk fileList tanımı ve subDirs tanımı arasındaki çözümünüze, her dosya için tam yol ve dosya adı döndürecektir. - Doresoom
@Doresoom: İyi bir öneri, FULLFILE ile birlikte kullanmaya devam etmeme rağmen, sizin için dosya ayırıcı seçimini (bu, UNIX ve Windows'taki farklıdır) seçtiği için. Ayrıca, sadece yapabilirsin fileList = strcat(dirName,filesep,fileList); CELLFUN kullanmak yerine, gereksiz dosya ayırıcıları ile sonuçlanabilir, ancak bu şekilde FULLFILE da sizin için ilgilenir. - gnovice
@gnovice, @Doreseoom - göre mathworks.com/access/helpdesk/help/techdoc/ref/dir.html'dir' döndürme sırası, OS bağımlıdır. Mesela, DOS DIRCMD değişkenini siparişi değiştiren bir şeye ayarladığınızda ne olacağından emin değilim. Oktav, tamam () ve yine de ilktir) işliyor ancak test etmek için MATLAB'ım yok. - mtrw
@gnovice: Bu OP'nin sorusunun ötesindedir, ancak işlevin normal ifadelerini oluşturmanın yararını buldum. 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  ve işlev imzasını getAllFiles(dirName, pattern) (2. hatta son satırda) - Peter D
Harika cevap, teşekkürler! 2 ek parametreyi desteklemek için kodu hazırladım - stackoverflow.com/a/26449095/69555 - Oz Radiano


Arıyorsun dir dizin içeriğini döndürmek için.

Sonuçların üstesinden gelmek için aşağıdakileri yapabilirsiniz:

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

Bu size aşağıdaki formatta çıkış vermelidir, ör .:

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

22
2018-04-16 13:41



Alt dizinlerdeki dosyaları içeren, ancak dizinin kendisi hariç, yinelemeli olarak arama yapabilir misiniz? - Gtker
Nasıl hariç tutulur? . ve .. ? - Gtker
elle test etmek . ve .. - Jason S
özyinel olarak: programınızı art arda çalışmak üzere yazın - Jason S
@Runner: hariç tutmak için. ve .., dir çıkışındaki ilk iki girişi kaldırın. Ya da, belirli bir dosya türü arıyorsanız, koş dir('*.ext')dizinleri otomatik olarak hariç tutan (elbette .ext ile bitmedikçe) - Jonas


Bahsedilen kodu kullandım bu harika cevap Benim durumumda ihtiyaç duyduğum 2 ek parametreyi desteklemek için genişletti. Parametreler, filtrelenecek dosya uzantıları ve dosyanın tam yolunun dosya adına bitip bitmeyeceğini belirten bir işarettir.

Umarım yeterince açıktır ve birisi onu faydalı bulur.

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

Kodu çalıştırmak için örnek:

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

13
2017-10-19 09:19





Ortadan kaldırmak için regexp veya strcmp kullanabilirsiniz . ve ..  Ya da isdir Yalnızca dizindeki dosyaları istemiyorsanız, klasörleri değil.

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

veya son iki satırı birleştirin:

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

Klasördeki klasörler listesi için. ve ..

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

Bu noktadan itibaren, kodu iç içe geçmiş bir döngüye atayabilmeniz ve her alt klasörde, her bir alt dizin için boş bir hücreye dönene kadar arama yapabilmeniz gerekir.


8
2018-04-16 14:59



+ 1, bu çok kompakt ama yinelemeli arama yapmıyor. - Gtker
@Runner: Bazıları için ve döngüleri kullanırsanız yapar ... ama şimdi bunu uygulamak için tembel davranıyorum. - Doresoom
+1, soruyu tam olarak cevaplamamasına rağmen, dizinleri hızlı bir şekilde silmenin bir yolunu sağlar. - jhfrontz


Bu cevap doğrudan soruyu cevaplamaz, ancak kutunun dışında iyi bir çözüm olabilir.

Gnovice'in çözümünü destekledim, ancak başka bir çözüm önermek istiyorum: İşletim sisteminizin sistem bağımlı komutunu kullanın:

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.

Pozitif:

  • Çok hızlı (linux'da 18000 dosyadan oluşan bir veritabanı için benim durumumda).
  • İyi test edilmiş çözümleri kullanabilirsiniz.
  • Seçmek için yeni bir sözdizimini öğrenmeniz veya yeniden keşfetmeniz gerekmez. *.wav Dosyalar.

Negatif:

  • Sistem bağımsız değilsiniz.
  • Ayrışması zor olabilecek tek bir dizeye güveniyorsunuz.

7
2018-04-02 08:31





Bunun için tek işlevli bir yöntem bilmiyorum ama kullanabilirsiniz genpath listesini tekrarlamak yalnızca alt dizinler. Bu liste noktalı virgülle ayrılmış bir dizin dizisi olarak döndürülür, bu nedenle strread kullanarak ayırmanız gerekir, yani.

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

Verilen dizini eklemek istemiyorsanız, ilk girişi kaldırın. dirlistyani dirlist(1)=[]; her zaman ilk giriş olduğu için.

Sonra her dizinde bir ilmek ile dosya listesini alın 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'ın çalıştığı platform için dizin ayırıcıyı döndürür.

Bu, hücre dizisinde tam yollara sahip dosya adlarının bir listesini verir. filenamelist. En düzgün çözüm değil, biliyorum.


3
2018-04-16 15:08



Performans nedeni için istemiyorum genpathAslında iki kere arar. - Gtker
GENPATH kullanmanın bir dezavantajı, yalnızca MATLAB yolunda izin verilen alt dizinleri içerecektir. Örneğin, adlandırılmış dizinleriniz varsa privatedahil edilmeyecekler. - gnovice


Bu, belirtilen formatta dosya isimleri almak için kullanışlı bir işlevdir (genellikle .mat) bir kök klasörde!

    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

Senin durumunda, aşağıdaki parçayı kullanabilirsiniz :)

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

1
2017-09-10 11:03





Her alt klasörün tam dosya yolunu almak için küçük bir değişiklik ancak neredeyse benzer bir yaklaşımla

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
2018-01-02 12:02