Changing specific characters in filenames across subfolders
14 views (last 30 days)
Show older comments
How can I change the first character "r" by another character "f" in all the filnames from multiple subfolders:
Directory folder1/folder2/folder3/
then, multiple files starting with "r" are located in multiple folders. Eg., (S001, S002) :
S001
rXXX11.nii
rXXX32.nii
S002
rXXX41.nii
rXXX63.nii
One unsuccesfull trial:
SourcePath ='D:\folder1\folder2\folder3\';
Participant = 'S';
index = 1001 : 1602;%Index the subjs according to their folder order (e.g., from 001 to 0602)
for i = 1 : length(index)
newParticipant=num2str(index(i));
newParticipant(1)='S';
%To setting the path's source folder iterating the subject folder
SourceFolder = fullfile([SourcePath,newParticipant]);
str=SourceFolder;
pat ='r*.nii';
newStr = replace(str,pat,'f*.nii');
end
Many thanks for any input.
0 Comments
Accepted Answer
Voss
on 28 Dec 2022
@julian gaviria: To address the problems you ran into:
"1. Is not recursive."
That's true; however, it is intended to operate on all folders starting with "S" at once, and find .nii files starting with "r" in each such folder.
SourcePath = 'D:\folder1\folder2\folder3';
dinfo = dir(fullfile(SourcePath, 'S*', 'r*.nii'));
% ^^^^^^^^^^ main folder
% ^^^^ sub-folder starting with "S"
% ^^^^^^^^ .nii file in sub-folder starting with "r"
"2.the expression must be changed [from '\\r(\w+\.nii)' to '\\r(\w*)']"
That's not true.
'\\r(\w+\.nii)' matches a backslash followed by a lowercase "r" followed by one or more alphanumeric or underscore characters followed by ".nii". Therefore it matches file names starting with "r" and ending with ".nii", as long as the rest of the file name contains only alphanumeric characters or underscores.
'\\r(\w*)' matches a backslash followed by a lowercase "r" followed by zero or more alphanumeric or underscore characters. It's not limited to matching file names ending with ".nii", and in fact it's not even limited to matching file names (i.e., without the "\.nii" specified, it can match directory names too).
Consider:
% your proposed regular expression works ok on this file name:
regexprep('C:\Users\Docs\S1000\rkehwr.nii','\\r(\w*)','\\f$1')
% but if any folder in the path happens to start with "r",
% you have a problem (here the "rocs" folder becomes "focs"):
regexprep('C:\Users\rocs\S1000\rkehwr.nii','\\r(\w*)','\\f$1')
The original works in both of those cases, because it is constrained by "\.nii" to match names of .nii files only:
regexprep('C:\Users\Docs\S1000\rkehwr.nii','\\r(\w+\.nii)','\\f$1')
regexprep('C:\Users\rocs\S1000\rkehwr.nii','\\r(\w+\.nii)','\\f$1')
But if you have file names that contain non-alphanumeric/underscore characters, they would be missed:
% "(" and ")" don't match the pattern -> file name is not changed
regexprep('C:\Users\Docs\S1000\rkehwr (Copy).nii','\\r(\w+\.nii)','\\f$1')
% "#" doesn't match the pattern -> file name is not changed
regexprep('C:\Users\rocs\S1000\rk#hwr.nii','\\r(\w+\.nii)','\\f$1')
% "=" doesn't match the pattern -> file name is not changed
regexprep('C:\rUsers\Docs\S1000\rke=wr.nii','\\r(\w+\.nii)','\\f$1')
A more general regular expression would be '\\r([^\\]*\.nii)', which will match a backslash followed by a lowercase "r" followed by zero or more non-backslash characters (that's the [^\\]* part) followed by ".nii". This way you're guaranteed to match the name of any .nii file that starts with "r". (Use non-backslash to match any base file name and avoid matching parent directory names.)
To show this regular expression on some of the previous examples:
% an easy case -> works
regexprep('C:\Users\Docs\S1000\rkehwr.nii','\\r([^\\]*\.nii)','\\f$1')
% a folder starting with "r" -> works
regexprep('C:\Users\rocs\S1000\rkehwr.nii','\\r([^\\]*\.nii)','\\f$1')
% a file name with special character(s) -> works
regexprep('C:\Users\rDocs\S1000\rkehwr (Copy).nii','\\r([^\\]*\.nii)','\\f$1')
"3. I do not manage to move/change the filenames."
Use cellfun since the file names are stored in cell arrays. (And you can omit "'uniform',0" since movefile returns a scalar.)
cellfun(@(OLD,NEW) movefile(OLD, NEW), filenames, newfilenames);
For completeness, the whole code (again, this code operates on all S* folders - do not put this code inside a loop) would be:
SourcePath = 'D:\folder1\folder2\folder3';
dinfo = dir(fullfile(SourcePath, 'S*', 'r*.nii'));
filenames = fullfile( {dinfo.folder}, {dinfo.name} );
newfilenames = regexprep(filenames, '\\r([^\\]*\.nii)', '\\f$1');
cellfun(@(OLD,NEW) movefile(OLD, NEW), filenames, newfilenames);
0 Comments
More Answers (1)
Walter Roberson
on 19 Dec 2022
SourcePath ='D:\folder1\folder2\folder3';
dinfo = dir(fullfile(SourcePath', 'S*', 'r*.nii'));
filenames = fullfile( {dinfo.folder}, {dinfo.name} );
newfilenames = regexprep(filenames, '\\r(\w+\.nii)', '\\f$1');
arrayfun(@(OLD,NEW) movefile(OLD, NEW), filenames, newfilename, 'uniform', 0);
1 Comment
See Also
Categories
Find more on Data Type Conversion 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!