How to rename a lot of mfiles in a folder

5 views (last 30 days)
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
Mohammad Shojaei Arani
Mohammad Shojaei Arani on 4 Dec 2022
Yes, just capitalize one letter or maximum the first two letters (I promise that I do not go beyound this).

Sign in to comment.

Accepted Answer

Image Analyst
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
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);

Sign in to comment.

More Answers (2)

Steven Lord
Steven Lord on 4 Dec 2022
Let's look at a simple example of what's in the temporary directory.
D = dir(tempdir)
D = 10×1 struct array with fields:
name folder date bytes isdir datenum
What's the first file (or "file") in that list?
D(1)
ans = struct with fields:
name: '.' folder: '/tmp' date: '04-Dec-2022 15:02:06' bytes: 0 isdir: 1 datenum: 7.3886e+05
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)
ans = struct with fields:
name: '..' folder: '/tmp' date: '04-Dec-2022 11:34:26' bytes: 0 isdir: 1 datenum: 7.3886e+05
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)
thepath = 0×0 empty char array thename = 1×0 empty char array
theextension = '.'
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
Image Analyst
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}

Sign in to comment.


Jan
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
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.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!