How to rename a lot of mfiles in a folder
4 views (last 30 days)
Show older comments
Hello,
I have a folder which contains many mfiles. I would like to change the name of these mfiles in
a for-loop (they are too many of them). I did google it and studied similar questions but I do not understand why
it does not work for me. To make things easy assume that I have a folder called D:\something which contains 4
mfiles m1.m, m2.m, u1.m,u2.m and only those which start with 'm' should change into capital M. So, at the end
I should get M1.m,M2.m,u1.m,u2.m . As you know the name of mfiles and the corresponding function name when we open it should be the same. So, this is the part I am not confident to do. So, I am not simpley asking something like "how to change 2 PDF files A1.pdf,A2.pdf
into, say, B1.pdf,B2.pdf ".
I have seen in google that people use the command 'dir' and then loop over the file names and if a particular file name should be
changed they use the command 'movefile'. To be honest, I get stocked in the begining. The answer to my question should be like the following:
files = dir('D:\something');
for i=1:length(files)
[~, NAME,~] = fileparts(files(id).name);
...
use 'movefiles'
end
I do not understand why when I, for instance, type [~, NAME,~] = fileparts(files(1).name) then I get
1×0 empty char array
I have no idea why it is like this (I hate it) !!!
Any idea?
Thanks
Babak
6 Comments
Image Analyst
on 4 Dec 2022
Edited: Image Analyst
on 4 Dec 2022
MATLAB does have a command to rename files. It's called movefile
You did not answer Jan. Do you just want to capitalize the first letter, or all the letters of the filename?
And not all m-files have or need a function definition line so you should just put one in if you have a function, but if you have a script, you don't need it. MATLAB cannot know your intent regarding this -- theirre Mind Reading Toolbox is still under development.
Accepted Answer
Image Analyst
on 4 Dec 2022
Try this:
folder = pwd; % or 'D:\something'
filePattern = fullfile(folder, '*.*'); % or '*.m' if you want only m-files.
fileList = dir(filePattern)
% Remove folders.
fileList([fileList.isdir]) = []
% Get all file names
allBaseFileNames = {fileList.name};
for k = 1 : numel(allBaseFileNames)
thisName = allBaseFileNames{k};
sourceFullFileName = fullfile(folder, thisName);
% Capitalize the first letter
thisName(1) = upper(thisName(1));
destinationFullFileName = fullfile(folder, thisName);
fprintf('Renaming %s to "%s".\n', sourceFullFileName, destinationFullFileName);
% Do the renaming: (Comment out to test without doing the actual renaming)
movefile(sourceFullFileName, destinationFullFileName);
end
2 Comments
Image Analyst
on 5 Dec 2022
If the first letter is already capitalized, then the source and destination file names are identical and it will throw an error so you need to skip the file if it's already in the proper format and does not need to be changed:
folder = pwd; % or 'D:\something'
filePattern = fullfile(folder, '*.*'); % or '*.m' if you want only m-files.
fileList = dir(filePattern)
% Remove folders.
fileList([fileList.isdir]) = []
% Get all file names
allBaseFileNames = {fileList.name};
for k = 1 : numel(allBaseFileNames)
thisName = allBaseFileNames{k};
sourceFullFileName = fullfile(folder, thisName);
% Capitalize the first letter
thisName(1) = upper(thisName(1));
destinationFullFileName = fullfile(folder, thisName);
if strcmp(destinationFullFileName, sourceFullFileName)
continue; % Skip this file if there is no change to the name.
end
fprintf('Renaming %s to "%s".\n', sourceFullFileName, destinationFullFileName);
% Do the renaming: (Comment out to test without doing the actual renaming)
movefile(sourceFullFileName, destinationFullFileName);
end
Here is a start at checking the function name inside the file. This is just for one single file so you should make it into a function and call it from inside the loop of the code above. I'm sure you'll be able to finish it.
% Open the file for reading in text mode.
fileID = fopen(fullFileName, 'rt');
% Read the first line of the file.
textLine = fgetl(fileID);
lineCounter = 1;
while ischar(textLine)
% Print out what line we're operating on.
fprintf('%s\n', textLine);
% See if the line contains both "function" and the basefilename.
[f, baseFileNameNoExt, ext] = fileparts(fullFileName)
if contains(textLine, 'function') && contains(textLine, baseFileNameNoExt, "IgnoreCase",true)
index = strfind(lower(textLine), lower(baseFileNameNoExt))
numChars = length(baseFileNameNoExt);
functionNameInFile = textLine(index : (index + numChars - 1));
if ~strcmp(fullFileName, baseFileNameNoExt)
% Function name in file does not match the name from the operating system.
% For example the capitalization may not match.
% Replace text line with fixed one using strrep. Then you'll have to create a
% temporary output file to write back out the fixed one.
% Then delete the original one and use movefile to rename the
% temporary file to the original filename.
end
end
% Read the next line.
textLine = fgetl(fileID);
lineCounter = lineCounter + 1;
end
% All done reading all lines, so close the file.
fclose(fileID);
More Answers (2)
Steven Lord
on 4 Dec 2022
Let's look at a simple example of what's in the temporary directory.
D = dir(tempdir)
What's the first file (or "file") in that list?
D(1)
This "file" refers to the current directory. There's at least one other file like this in your directory, and given what's in this directory it's the second "file". [These are not always the first and second file in the directory.]
D(2)
This refers to the parent of this directory, so cd .. will change into the parent directory of the current directory.
When I try to split the name of this first "file" into parts, what do I get?
[thepath, thename, theextension] = fileparts(D(1).name)
You probably want to filter out the directories. One way to do this would be to only move the file if files(id).isdir is not 1.
5 Comments
Steven Lord
on 5 Dec 2022
Those commands would match MATLAB script, function, or class files in that directory. They don't match live scripts or live functions with the .mlx extension. They also wouldn't list MATLAB data files with the .mat extension, MATLAB figure files (.fig), Simulink model files, etc. I don't know if any of those are in scope.
Image Analyst
on 5 Dec 2022
Steve, correct. Since he said ""rename a lot of mfiles in a folder" I assumed it was only mfiles with a filename extension of ".m". If he wants other extensions, like .fig, he can append those on like this:
filePattern1 = fullfile(folder, '*.m') % Full demo in my answer below.
filePattern2 = fullfile(folder, '*.fig') % Full demo in my answer below.
fileList = [dir(filePattern1); dir(filePattern2)]
allFileNames = {fileList.name}
Jan
on 4 Dec 2022
Edited: Jan
on 4 Dec 2022
folder = 'D:\something';
files = dir(folder);
files = file(~[files.isdir]); % Files only!
for k = 1:numel(files) % numel() is safer than lenght()
oldFile = files(k).name;
[~, name, ~] = fileparts(oldFile);
newFile = [upper(name), '.m'];
% Or maybe:
% newFile = oldfile;
% newFile(1) = upper(newFile(1));
... movefile(fullfile(folder, oldFile), fullfile(folder, newFile)) ?!?
end
Under Windows you cannot use MOVEFILE to rename a file, if only the case differs. "m1.m" and "M1.m" are considered as equal by the operating system (but not by Matlab).
Another solution is an indirection: Use movefile() to rename the file "m1.m" to "tmp_ThisIsAUniqueName1234" and then to "M1.m".
Before I can suggest explicit code for the renaming, you have to define the wanted modification exactly.
2 Comments
Jan
on 5 Dec 2022
Edited: Jan
on 5 Dec 2022
You do not have to change the contents of the variable twice, but the name of the file.
Unfortunately you still do not reveal, how you want to modify the name of the file. Should only the 'm' be converted to 'M'? Then:
folder = 'D:\something';
files = dir(folder);
files = file(~[files.isdir]); % Files only!
for k = 1:numel(files) % numel() is safer than lenght()
oldFile = files(k).name;
[~, name] = fileparts(oldFile);
newFile = [upper(name), '.m']; % Maybe?!?
tempFile = fullfile(folder, 'tempFile.tmp');
movefile(fullfile(folder, oldFile), tempFile); % 1st renaming
movefile(tempfile, fullfile(folder, newFile)); % 2nd renaming
end
Using the FileExchange submission FileRename is not hard: Either download the submission from the FileExchange and compile it by: mex -O FileRename.c, or download the pre-compiled mex file. Then:
folder = 'D:\something';
files = dir(folder);
files = file(~[files.isdir]); % Files only!
for k = 1:numel(files) % numel() is safer than lenght()
oldFile = files(k).name;
[~, name] = fileparts(oldFile);
newFile = [upper(name), '.m']; % Maybe?!?
FileRename(fullfile(folder, oldFile), fullfile(folder, newFile));
end
The FileExchange is full of gems. It is worth to learn how to use the tenthousand of useful submissions of other Matlab programmers.
See Also
Categories
Find more on Testing Frameworks in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!