How to batch rename files to 3-digit numbers? - matlab

I apologize in advance that this question is not specific. But my goal is to take a bunch of image files, which are currently named as: 0.tif, 1.tif, 2.tif, etc... and rename them just as numbers to 000.tif, 001.tif, 002.tif, ... , 010.tif, etc...
The reason I want to do this is because I am trying to load the images into matlab and for batch processing but matlab does not order them correctly. I use the dir command as dir(*.tif) to get all the images and load them into an array of files that I can iterate over and process, but in this array element 1 is 0.tif, element 2 is 1.tif, element 3 is 10.tif, element 4 is 100.tif, and so on.
I want to keep the ordering of the elements as I process them. However, I do not care if I have to change the order of the elements BEFORE processing them (i.e. I can make it work to rename, for example, 2.tif to 10.tif if I had to) but I am looking for a way to convert the file names the way I initially described.
If there is a better way to get matlab to properly order the files when it loads them into the array using dir please let me know because that would be much easier.
Thanks!!

You can do this without having to rename the files, if you want. When you grab the files using dir, you'll have a list of files like so:
files =
'0.tif'
'1.tif'
'10.tif'
...
You can grab just the numeric part using regexp:
nums = regexp(files,'\d+','match');
nums = str2double([nums{:}]);
nums =
0 1 10 11 12 ...
regexp returns its matches as a cell-array, the second line converts it back to actual numbers.
We can now get an actual numeric order by sorting the resulting array:
[~,order] = sort(nums);
and then put the files in the correct order:
files = files(order);
This should (I haven't tested it, I don't have a folder full of numerically labelled files handy) produce a list of files like so:
files=
'0.tif'
'1.tif'
'2.tif'
'3.tif'
...

this is partially dependent on the version of matlab you have. If you have a version with findstr this should work well
num_files_to_rename = numel(name_array);
for ii=1:num_files_to_rename
%in my test i used cells to store my strings you may need to
%change the bracket type for your application
curr_file = name_array{ii};
%locates the period in the file name (assume there is only one)
period_idx = findstr(curr_file ,'.');
%takes everything to the left of the period (excluding the period)
file_name = str2num(curr_file(1:period_idx-1));
%zeropads the file name to 3 spaces using a 0
new_file_name = sprintf('%03d.tiff',file_name)
%you can uncomment this after you are sure it works as you planned
%movefile(curr_file, new_file_name);
end
the actual rename operation movefile is commented out for now. make sure the output names are as you expect before uncommenting it and renaming all the files.
EDIT there is no real error checking in this code, it just assumes every file name has one and only one period, and an actual number as the name

The Batch file below do the rename of the files you want:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%f in ('dir /B *.tif') do (
set "name=00%%~Nf"
ren "%%f" "!name:~-3!.tif"
)
Note that this solution preserve the same order of your original files, even if there are missing numbers in the sequence..

Related

Matlab - Help in listing files using a name-pattern

I'm trying to create a function that lists the content of a folder based on a pattern, however the listing includes more files than needed. I'll explain by an example: Consider a folder containing the files
file.dat
file.dat._
file.dat.000
file.dat.001
...
file.dat.999
I am interested only in the files that are .000, .001 and so on. The files file.dat and file.dat._ are to be excluded.
The later numbering can also be .0000,.0001 and so on, so number of digits is not necessarily 3.
I tried using the Dir command with the pattern file.dat.* - this included file.dat for some reason (Why the last comma treated differently?) and file.dat._, which was expected.
The "obvious" set of solutions is to add an additional regular expression or length check - however I would like to avoid that, if possible.
This needs to work both under UNIX and Windows (and preferably MacOS).
Any elegant solutions?
Get all filenames with dir and filter them using with the regex '^file\.dat\.\d+$'. This matches:
start of the string (^)
followed by the string file.dat. (file\.dat\.)
followed by one or more digits (\d+)
and then the string must end ($)
Since the output of dir is a cell array of char vectors, regex returns a cell array with the matching indices of each char vector. The matching indices can only be 1 or [], so any is applied to each cell's content to reduce it to true or false The resulting logical index tells which filenames should be kept.
f = dir('path/to/folder');
names = {f.name};
ind = cellfun(#any, regexp(names, '^file\.dat\.\d+$'));
names = names(ind);

Reading all the files in sequence in MATLAB

I am trying to read all the images in the folder in MATLAB using this code
flst=dir(str_Expfold);
But it shows me output like this. which is not the sequence as i want.
Can anyone please tell me how can i read all of them in sequence?
for giving downmark, please explain the reason for that too.
By alphabetical order depth10 comes before depth2. If at all possible, when creating string + num type filenames, use a fixed width numerical part (e.g. depth01, depth02) - this tends to avoid sorting problems.
If you are stuck with the filenames you have, and know the filename pattern, though, you can not bother using dir at all and create your filename list in the correct order in the first place:
for n = 1:50
fname = sprintf('depth%d.png',n);
% code to read and process images goes here
end
From the Matlab forums, the dir command output sorting is not specified, but it seems to be purely alphabetical order (with purely I mean that it does not take into account sorter filenames first). Therefore, you would have to manually sort the names. The following code is taken from this link (you probably want to change the file extension):
list = dir(fullfile(cd, '*.mat'));
name = {list.name};
str = sprintf('%s#', name{:});
num = sscanf(str, 'r_%d.mat#');
[dummy, index] = sort(num);
name = name(index);

looping and ordering extracted data in MatLab

I have hundreds of data files, named file001~file400 for example, and should pick a numeric value from each. I know how to pick each number, but, since there are too many files, I need to loop the command and order all extracted numbers with regard to the number of corresponding file. I appreciate any help.
The problem is to loop over all files. This can be done in the following way:
for i = 1:400
filename = sprintf('file%03d',i);
// do the number picking, etc. using the filename.
end
EDIT: Per request, for filenames FT00100 to FT05320, we we make two small changes, one in the loop range and one in the first parameter to sprintf:
for i = 100:5320
filename = sprintf('FT%05d',i);
// do the number picking, etc. using the filename.
end

Loading MATLAB .mat files in alphanumerical order

I'm currently attempting to load a number of MATLAB files which all contain the same variable in order to make a matrix of all the values.
These files all start with a number (i.e. 40_analysed.mat), which was previously extracted from different raw data files using regular expressions, meaning I have a vector composed of all the individual numbers (id).
When I try to load the values and display the data for all individuals in a single matrix using the code below, the files aren't loaded alphanumerically (i.e. according to id), instead appearing to be loaded randomly.
file = dir('*_analysed.mat');
for i=1:length(id);
load(file(i).name,'means');
overallThresholds{i} = means;
end
overallMeans = cell2mat(overallThresholds)
How could I do this so the resulting matrix would be in the correct order? Apologies if this question doesn't make much sense, the problem is a little hard to articulate!
If your filenames don't have a fixed-precision number (as #FakeDIY points out, that would mean they would already be sorted), you could do something like this:
file = dir('*_analysed.mat');
overalThresholds = cell(1, length(id));
IDs = zeros(1, length(id));
for i = 1:length(id)
fileName = file(i).name;
IDs(i) = str2double( strrep( fileName, '_analysed.mat', '' ) );
data = load(fileName, 'means');
overallThresholds{i} = data.means;
end
[~, reordering] = sort(IDs);
overallThresholds = overallThresholds(reordering);
In other words, store the file ID in a separate array as you're going along, and then reorder overallThresholds to be in sorted order of IDs using the second output of SORT.
(I also pre-allocated the arrays, and use the functional form of LOAD, but you don't really need to do that).
When one uses dir command, it is not promised that the results will be in alphabetical order. In fact, the manual says explicitly that:
dir lists the files and folders in the MATLAB current folder. Results
appear in the order returned by the operating system.
Even if you did get this in alphabetical order, nothing assures you that you will get it next time. Thus, you must order the results from dir using sort command.
[~,order] = sort( {file.name} );
file = file(order);

Loop through files in a folder in matlab

I have a set of days of log files that I need to parse and look at in matlab.
The log files look like this:
LOG_20120509_120002_002.csv
(year)(month)(day)_(hour)(minute)(second)_(log part number)
The logs increment hourly, but sometimes the seconds are one or two seconds off (per hour) which means i need to ignore what they say to do loadcsv.
I also have another file:
LOG_DATA_20120509_120002.csv
which contains data for the whole hour (different data).
The overall objective is to:
loop through each day
loop through each hour
read in LOG_DATA for whole hour
loop through each segment
read in LOG for each segment
compile a table of all the data
I guess the question is then, how do i ignore the minutes of the day if they are different? I suspect it will be by looping through all the files in the folder, in which case how do i do that?
Looping through all the files in the folder is relatively easy:
files = dir('*.csv');
for file = files'
csv = load(file.name);
% Do some stuff
end
At first, you must specify your path, the path that your *.csv files are in there
path = 'f:\project\dataset'
You can change it based on your system.
then,
use dir function :
files = dir (strcat(path,'\*.csv'))
L = length (files);
for i=1:L
image{i}=csvread(strcat(path,'\',file(i).name));
% process the image in here
end
pwd also can be used.