How to loop through a specific file in various subfolders inside a main folder?

13 views (last 30 days)
I have a main folder containing several subfolders in it, named in a logical way (eg. damage1_case20; damage2_case20; (...); damagei_case20). Each subfolder has several files within them, all sharing the same name between subfolders. My goal is to create a loop in a way that the code would open one subfolder (starting with damage1_case20), open a specific file inside that subfolder (eg. calculation.mat), do what I want it to do to that file, save the new version of the file (eg. calculation_fix.mat) inside that subfolder, then move on to the next subfolder (which would be damage2_case20) and repeat the proccess until the end (damagei_case20).
  1 Comment
Stephen23
Stephen23 on 12 Apr 2023
Whatever you do, avoid using slow and hard-to-debug CD in your code!
The simple approach is to get DIR to do most of of this task as possible.

Sign in to comment.

Answers (3)

Bjorn Gustavsson
Bjorn Gustavsson on 4 Apr 2023
For this I (sometimes) do this type of thing:
proj_root_dir = '/full/path/to/project';
data_dirs = {'damage1_case20','damage2_case20','damage3_case20'}; % etc, etc
% or I programmatically extract the data-directories with dir.
file2process = 'calculation.mat';
for iD = 1:numel(data_dirs)
cd(proj_root_dir)
cd(data_dirs{iD})
try
results = process_datafile(file2process)
[~,fnm,ext] = fileparts(file2process);
fnm2save = [fnm,'_fix',ext]; % this save-part might be better
save(fnm2save,'results'); % inside the processing-function
% but you get the idea
catch
disp(['something dodgy happened processing file: ',fullfile(data_dirs{iD},file2process)])
end
end
HTH

Image Analyst
Image Analyst on 11 Apr 2023
Edited: Image Analyst on 11 Apr 2023
Try this robust and well commented demo:
% Finds all the subfolders under a top level folder and then for each subfolder, processes the files within that folder.
% NOTE: this does not process files in the top level folder. It only processes files in subfolders of the top level folder.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format compact;
% Define input folder.
% CHANGE THIS FOLDER NAME!!!!!!
topLevelFolder = pwd;
% Check to see that the folder exists.
if ~isfolder(topLevelFolder)
errorMessage = sprintf('Error: The following input folder does not exist:\n%s', topLevelFolder);
uiwait(warndlg(errorMessage));
return;
end
% Get a list of files to process.
filePattern = fullfile(topLevelFolder, '*.*'); % All files in topLevelFolder ONLY.
fileList = dir(filePattern);
% Get only files with the "isdir" flag set. These will be subfolders.
subFolders = fileList([fileList.isdir]);
% Get a cell array of the subfolder names
allSubFolderNames = fullfile(topLevelFolder, {subFolders.name})'
% Get rid of system folders . and ..
systemFolderIndexes = endsWith(allSubFolderNames, '\.') | endsWith(allSubFolderNames, '\..')
subFolders(systemFolderIndexes) = []; % Delete those items by setting equal to null.
% Count how many subfolders we have.
numFolders = length(subFolders);
fprintf('Found %d subfolders inside "%s".\n', numFolders, topLevelFolder)
% If you want you can get a cell array of the subfolder names
allSubFolderNames = fullfile(topLevelFolder, {subFolders.name})'
% Do the processing.
for k = 1 : numFolders
% Get the full path of this one subfolder..
fullSubFolderName = allSubFolderNames{k};
fprintf(1, '\nNow processing folder #%d of %d: "%s".\n', ...
k, numFolders, fullSubFolderName);
% Now get a list of files within this subfolder.
fileList = dir(fullSubFolderName);
% Get a list of files only -- not . and .. and not any subfolders of this subfolder.
filesInSubFolder = fileList(~[fileList.isdir]);
% Count the number of files in this subfolder.
numFiles = numel(filesInSubFolder);
for k2 = 1 : numFiles
thisBaseFileName = filesInSubFolder(k2).name;
thisFullFileName = fullfile(fullSubFolderName, thisBaseFileName);
fprintf(' Processing file #%d of %d : "%s".\n', k2, numFiles, thisBaseFileName)
% Now do whatever you want with thisFullFileName
% such as opening it, copying or moving it somewhere, or whatever.
end
end
message = sprintf('Done processing %d files in %d subfolders of \n"%s".', ...
numFiles * numFolders, numFolders, topLevelFolder);
uiwait(msgbox(message, 'modal'));
In the innermost loop you can open the mat file, change the variables, create a new output filename, and save it.

Stephen23
Stephen23 on 12 Apr 2023
Edited: Stephen23 on 12 Apr 2023
The simple robust MATLAB approach is to get DIR to do most of the heavy lifting. It is very easy for DIR to loop over subfolders and to avoid dot-directory names and to list only the file you want from each subfolder:
P = 'absolute or relative path to where the subfolders are';
S = dir(fullfile(P,'damage*_case20','calculation.mat'));
for k = 1:numel(S)
F = fullfile(S(k).folder,S(k).name);
D = load(F);
% do whatever with the imported file data D
[Q,N,E] = fileparts(F);
F = fullfile(Q,sprintf('%s',N,'_fix',E));
save(F,'-struct',D)
end

Products


Release

R2018a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!