Làm cách nào để lấy tất cả các tệp trong một thư mục cụ thể trong MATLAB?


102

Tôi cần lấy lại tất cả các tệp đó D:\dicvà lặp lại chúng để xử lý riêng lẻ.

MATLAB có hỗ trợ loại hoạt động này không?

Nó có thể được thực hiện trong các script khác như PHP, Python ...

Câu trả lời:


130

Cập nhật: Vì bài đăng này khá cũ và tôi đã sửa đổi tiện ích này rất nhiều để sử dụng riêng trong thời gian đó, tôi nghĩ tôi nên đăng một phiên bản mới. Đang mới nhất của tôi có thể được tìm thấy trên MathWorks file Trao đổi : dirPlus.m. Bạn cũng có thể lấy nguồn từ GitHub .

Tôi đã thực hiện một số cải tiến. Giờ đây, nó cung cấp cho bạn các tùy chọn để thêm trước đường dẫn đầy đủ hoặc chỉ trả lại tên tệp (được kết hợp từ DoresoomOz Radiano ) và áp dụng mẫu biểu thức chính quy cho tên tệp (được kết hợp từ Peter D ). Ngoài ra, tôi đã thêm khả năng áp dụng chức năng xác nhận cho từng tệp, cho phép bạn chọn chúng dựa trên các tiêu chí khác ngoài tên của chúng (tức là kích thước tệp, nội dung, ngày tạo, v.v.).


LƯU Ý: Trong các phiên bản mới hơn của MATLAB (R2016b trở lên), dirhàm có khả năng tìm kiếm đệ quy! Vì vậy, bạn có thể thực hiện việc này để nhận danh sách tất cả *.mcác tệp trong tất cả các thư mục con của thư mục hiện tại:

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

Mã cũ: (cho hậu thế)

Đây là một hàm tìm kiếm đệ quy qua tất cả các thư mục con của một thư mục nhất định, thu thập danh sách tất cả các tên tệp mà nó tìm thấy:

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

Sau khi lưu hàm trên ở đâu đó trên đường dẫn MATLAB của bạn, bạn có thể gọi nó theo cách sau:

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

3
+1 - Giải pháp tuyệt vời. Tôi không biết có cần thiết không, nhưng nếu bạn chèn dòng: fileList = cellfun (@ (x) strcat ([dirName, '\'], x), fileList, 'UniformOutput', 0); vào giải pháp của bạn giữa định nghĩa fileList đầu tiên và định nghĩa subDirs, nó sẽ trả về đường dẫn đầy đủ và tên tệp cho mỗi tệp.
Doresoom

2
@Doresoom: Đề xuất tốt, mặc dù tôi đã sử dụng FULLFILE thay thế, vì nó xử lý lựa chọn phân tách tệp cho bạn (điều này khác nhau trên UNIX và Windows). Ngoài ra, bạn chỉ có thể làm fileList = strcat(dirName,filesep,fileList);thay vì sử dụng CELLFUN, mặc dù bạn có thể kết thúc với các dấu tách tệp không cần thiết theo cách đó, mà FULLFILE cũng sẽ giải quyết cho bạn.
gnovice

2
@gnovice, @Doreseoom - Theo mathworks.com/access/helpdesk/help/techdoc/ref/dir.html , thứ tự mà 'dir' trả về phụ thuộc vào hệ điều hành. Tôi không chắc điều gì sẽ xảy ra, chẳng hạn như bạn đặt biến DOS DIRCMD thành thứ gì đó thay đổi thứ tự. Octave xử lý nó ổn (. Và .. vẫn là đầu tiên) nhưng tôi không có MATLAB để kiểm tra.
mtrw

2
@gnovice: Điều này nằm ngoài câu hỏi của OP, nhưng tôi thấy hữu ích khi xây dựng biểu thức chính quy vào hàm. 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 và thay đổi chữ ký hàm thành getAllFiles(dirName, pattern)(cũng ở dòng thứ 2 đến dòng cuối cùng)
Peter D

1
Câu trả lời tuyệt vời, cảm ơn! Tôi đã xây dựng mã để hỗ trợ 2 tham số bổ sung - stackoverflow.com/a/26449095/69555
Oz Radiano

25

Bạn đang tìm kiếm dir để trả lại nội dung thư mục.

Để lặp lại các kết quả, bạn chỉ cần làm như sau:

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

Điều này sẽ cung cấp cho bạn đầu ra ở định dạng sau, ví dụ:

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

Bạn có thể làm cho nó tìm kiếm đệ quy bao gồm các tệp trong thư mục con nhưng loại trừ chính thư mục không?
Gtker

Không nằm ngoài đầu tôi, không (tôi không còn truy cập thường xuyên vào Matlab nữa), nhưng điều này có thể giúp bạn: mathworks.com/matlabcentral/fileexchange/…
James B

2
Làm thế nào để loại trừ ...?
Gtker

5
@Runner: để loại trừ. và .., loại bỏ hai mục đầu tiên trong đầu ra của dir. Hoặc, trong trường hợp bạn đang tìm kiếm một loại tập tin cụ thể, chạy dir('*.ext'), tự động loại trừ các thư mục (trừ khi họ kết thúc trong .ext, tất nhiên)
Jonas

14

Tôi đã sử dụng mã được đề cập trong câu trả lời tuyệt vời này và mở rộng nó để hỗ trợ 2 tham số bổ sung mà tôi cần trong trường hợp của mình. Các tham số là phần mở rộng tệp cần lọc và cờ cho biết có nên nối đường dẫn đầy đủ với tên tệp hay không.

Tôi hy vọng nó đủ rõ ràng và ai đó sẽ thấy nó có lợi.

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

Ví dụ để chạy mã:

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

8

Bạn có thể sử dụng regexp hoặc strcmp để loại bỏ ... Hoặc bạn có thể sử dụng isdirtrường nếu bạn chỉ muốn tệp trong thư mục, không phải thư mục.

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

hoặc kết hợp hai dòng cuối cùng:

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

Đối với danh sách các thư mục trong thư mục loại trừ. và ..

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

Từ thời điểm này, bạn sẽ có thể ném mã vào một vòng lặp for lồng nhau và tiếp tục tìm kiếm từng thư mục con cho đến khi tên dirnames của bạn trả về một ô trống cho mỗi thư mục con.


@Runner: Nó đúng nếu bạn sử dụng một số vòng lặp for và while ... nhưng tôi lười triển khai điều đó ngay bây giờ.
Doresoom

+1 mặc dù nó không trả lời chính xác câu hỏi, nó cung cấp một cách để loại bỏ các thư mục một cách nhanh chóng.
jhfrontz

7

Câu trả lời này không trực tiếp trả lời câu hỏi nhưng có thể là một giải pháp tốt bên ngoài hộp.

Tôi đã ủng hộ giải pháp của gnovice, nhưng muốn cung cấp một giải pháp khác: Sử dụng lệnh phụ thuộc hệ thống của hệ điều hành của bạ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.

Tích cực:

  • Rất nhanh (trong trường hợp của tôi đối với cơ sở dữ liệu gồm 18000 tệp trên linux).
  • Bạn có thể sử dụng các giải pháp đã được thử nghiệm tốt.
  • Bạn không cần phải học hoặc phát minh lại một cú pháp mới để chọn *.wavcác tệp tức là .

Tiêu cực:

  • Bạn không độc lập với hệ thống.
  • Bạn dựa vào một chuỗi đơn lẻ có thể khó phân tích cú pháp.

3

Tôi không biết phương pháp một hàm cho việc này, nhưng bạn chỉ có thể sử dụng genpathđể đệ quy danh sách các thư mục con . Danh sách này được trả về dưới dạng một chuỗi thư mục được phân tách bằng dấu chấm phẩy, vì vậy bạn sẽ phải tách nó ra bằng cách sử dụng strread, tức là

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

Nếu bạn không muốn bao gồm thư mục đã cho, hãy xóa mục nhập đầu tiên của dirlist, tức là dirlist(1)=[];vì nó luôn là mục nhập đầu tiên.

Sau đó, lấy danh sách các tệp trong mỗi thư mục với một vòng lặp 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 trả về dấu phân tách thư mục cho nền tảng mà MATLAB đang chạy.

Điều này sẽ cho bạn một danh sách tên tập tin với đường dẫn đầy đủ trong mảng di động filenamelist . Tôi biết không phải là giải pháp gọn gàng nhất.


Vì lý do hiệu suất mà tôi không muốn genpath, về cơ bản nó sẽ tìm kiếm hai lần.
Gtker

2
Một hạn chế khi sử dụng GENPATH là nó sẽ chỉ bao gồm các thư mục con được phép trên đường dẫn MATLAB. Ví dụ: nếu bạn có các thư mục được đặt tên private, chúng sẽ không được đưa vào.
gnovice

1

Đây là một chức năng tiện dụng để lấy tên tệp, với định dạng được chỉ định (thường là .mat) trong thư mục gốc!

    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

Trong trường hợp của bạn, bạn có thể sử dụng đoạn mã sau :)

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

0

Với một chút sửa đổi nhưng cách tiếp cận gần như tương tự để có được đường dẫn tệp đầy đủ của mỗi thư mục con

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  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.