Copying and renaming multiple files from multiple directories into one directory

30 views (last 30 days)
Hey everyone,
I have been stuck on this for quite a while now (over a week).
I am trying to create a directory which contains files from 5 other directories. The files in these 5 other directories all have the same names, so I have to create a code that allows me to both copy the files and also rename them in the process. I have compiled code so far using guidelines posted in other threads, so I will upload that here.
Structure of the directory:
1_folder1
1_folder2
1_folder3
1_folder4
1_folder5
Each of the folders contains files:
File1.txt
File2.txt
File3.txt
File4.txt
File5.txt
The contents within these files are just the name of the folder and the name of the file (Folder1_File1...etc)
Here is the code I have compiled so far:
%%
clear
%% Start on the directory (folder) where all the other folders will be
oldir = cd
%% Make a file showing all the directories in the main directory
topLevelFolder = pwd;
files = dir(topLevelFolder);
dirFlags = [files.isdir];
subFolders = files(dirFlags); % A structure with extra info.
subFolderNames = {subFolders(3:end).name} % Start at 3 to skip . and ..
%% Create a new folder, if this folder doesn't exist already
outputFolder = fullfile(pwd, 'MergedFolder');
if ~exist(outputFolder, 'dir')
mkdir(outputFolder);
end
%% Integrate new directory moving loop with code to copy files
for u = 1:length(subFolderNames)
folderName = subFolderNames(u);
charFolderName = char(folderName)
cd(charFolderName);
inputfiles = dir(fullfile('*.txt'));
fileNames = {inputfiles.name};
for j = 1:length(fileNames)
thisFileName = fileNames{j};
% Prepare the input filename.
inputFullFileName = fullfile(pwd, thisFileName);
% Make a list of all the files with their current names
AllFiles{j+height(AllFiles),1} = thisFileName;
% Prepare the output filename.
outputBaseFileName = sprintf('%s_T.txt', thisFileName(1:end-4));
outputFullFileName = fullfile(outputFolder, outputBaseFileName)
% Do the copying and renmaing all at once.
copyfile(inputFullFileName, outputFullFileName);
end
cd(oldir);
end
This is where I am stuck. The 2nd for loop just does not seem to be working. I know the first for loop works because I was able to go into each directory and inesrt a new directory, as shown below:
for i = 1:length(subFolderNames)
folderName = subFolderNames(i);
charFolderName = char(folderName)
cd(charFolderName);
mkdir('Testing');
cd(oldir);
end
Any help would be greatly appreciated!
  2 Comments
Stephen23
Stephen23 on 12 Aug 2022
Edited: Stephen23 on 12 Aug 2022
"The 2nd for loop just does not seem to be working."
One reason is this line of code:
inputfiles = dir(fullfile('*.txt'));
within which the FULLFILE does nothing because you did not provide it with the path to the folder where the files are saved, which means that a) FULLFILE is completely superfluous and b) your code does not look for files in the those subfolders, instead looking in the current directory. Probably you intended to look in those subfolders, but that is not how you wrote your code.
"Any help would be greatly appreciated!"
Simplify your code.
Do not use CD to access data files. Use absolute/relative filenames.
"Start at 3 to skip . and .." is latent buggy because there is no guarantee that dot directory names will be the first two names returned by DIR. Use SETDIFF or ISMEMBER to remove them, or avoid the issue by specifying more of the folder names (with wildcards as required).
thisFileName(1:end-4) is a latent buggy approach to remove the file extension, replace with FILEPARTS.
You do not need to convert the DIR output structure to cell arrays of names, just access the structure elements.
Feston Idrizi
Feston Idrizi on 12 Aug 2022
Edited: Feston Idrizi on 12 Aug 2022
Dear Stephen,
Will try all of the suggestions to improve the code I alraedy wrote, although your code (below) worked quite well. Thanks again!

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 12 Aug 2022
Edited: Stephen23 on 12 Aug 2022
This should get you started:
P = 'absolute or relative path to the source parent directory';
Q = 'absolute or relative path to the destination directory';
mkdir(Q)
S = dir(fullfile(P,'1_folder*')); % better to specify subfolder match
S(~[s.isdir]) = [];
for ii = 1:numel(S)
D = fullfile(P,S(ii).name,'*.txt');
T = dir(D);
for jj = 1:numel(T)
Old = fullfile(P,S(ii).name,T(jj).name);
New = fullfile(Q,sprintf('%s_%s',S(ii).name,T(jj).name));
copyfile(Old,New)
end
end
  1 Comment
Feston Idrizi
Feston Idrizi on 12 Aug 2022
Edited: Feston Idrizi on 12 Aug 2022
Dear Stephen,
This worked like a charm, with some minor modifications. For some reason "S = dir(fullfile(P,'1_folder*'));" was only calling the 1st folder. I changed the code there slightly to:
S = dir(fullfile(P));
S(~[S.isdir]) = []; % delete empty dir
S = S(~startsWith({S.name},'.')); % delete all dir starting with '.'
The rest I left the same and I was able to get all the files copied and renamed.
Thanks a ton!

Sign in to comment.

More Answers (0)

Categories

Find more on File Operations in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!