Matlab - Renaming files sequentially (Opposite direction) - matlab

I Have sequential files for example:
hi_0001.edf
hi_0002.edf
hi_0003.edf
hi_0004.edf
I want to rename them plus number them the opposite direction (Start from end to beginning) so that:
"hi_0001.edf" becomes "hello_0004.edf"
"hi_0002.edf" becomes "hello_0003.edf"
"hi_0003.edf" becomes "hello_0002.edf"
"hi_0004.edf" becomes "hello_0001.edf"
I have the following program that can rename the files but gives them the same numbers (From beginning to end):
%//' Directory where TIFF images are present
directory = 'C:\Users\opd28\Desktop\folder\';
%//' files pattern with absolute paths
filePattern = fullfile(directory, 'hi_*.edf');
%// Get the filenames
old_filename = cellstr(ls(filePattern)) ;
%// Get numbers associated with each file
file_ID = strrep(strrep(old_filename,'hi_',''),'.edf','');
file_ID_doublearr = str2double(file_ID);
file_ID_doublearr = file_ID_doublearr - min(file_ID_doublearr)+1;
file_ID = strtrim(cellstr(num2str(file_ID_doublearr)));
%// Get zeros string to be pre-appended to each filename
str_zeros = arrayfun(#(t) repmat('0',1,t),4-cellfun(#numel,file_ID),'uni',0) ;
%// Generate new filenames
new_filename = strcat('hello_',str_zeros,file_ID,'.edf') ;
%// Finally rename files with the absolute paths
cellfun(#(m1,m2)movefile(m1,m2),fullfile(directory,old_filename),fullfile(directory,new_filename)) ;
The code above generates the following:
"hi_0001.edf" becomes "hello_0001.edf"
"hi_0002.edf" becomes "hello_0002.edf"
"hi_0003.edf" becomes "hello_0003.edf"
"hi_0004.edf" becomes "hello_0004.edf"
What do I need to add to make the new file names start from the end towards the beginning.

You can flip the file_ID_doublearr variable, and you'll have it.
file_ID_doublearr = str2double(file_ID);
file_ID = file_ID_doublearr(end:-1:1); % or 'flipud' / 'fliplr'
Now you can finish with the rest of your script, and the file names should be ordered from 4 to 1.
I guess this is the line where you tried to change the numbers:
file_ID_doublearr = max(file_ID_doublearr) - file_ID_doublearr + 1;
If you did one of the following, it would have worked:
file_ID_doublearr = file_ID_doublearr - min(file_ID_doublearr)+1;
or
file_ID_doublearr = flipud(file_ID_doublearr);
Note, I don't have MATLAB here, but I can't imagine this not working. Please let me know if there's an error.

Related

how to run multiple text file in matlab and get separate output file?

Hi I am having multiple text file name ABR1.txt,ABR2.txt,....ABR1000.txt
I have wrote down matlab code for distance calculation. So I want that all the file present in the current folder should run in this code and provide separate output file. So I am trying but only one ABR1.txt is giving output. Please check it and let me know what i can do?
clc
clear all
for n=1:2
filename = ['ABR', int2str(n), '.txt'];
Pop=load(filename);
[m n] = size(Pop);
n = m;
Dist = zeros(m, n);
for i = 1 : m
for j = 1 : n
Dist(i, j) = sqrt((Pop(i, 1) - Pop(j, 1)) ^ 2 + ...
(Pop(i, 2) - Pop(j, 2)) ^ 2);
end
end
Dist
q=(1-(3/8)*Dist)
filename = ['ABRa', int2str(n), '.txt'];
save(filename, 'q', '-ascii');
end
You are using the variable "n" both as your loop/file counter, and as the size of the matrix you read. I don't know what the data you're loading looks like, but if "n" ends up at a value of 1, then you'll only ever write the file name with "1" in it. You may actually be writing it twice, but both times have the same file name.
I would start by changing your for loop to use some other variable name:
for iFile = 1:2
Then also change it in the file name:
filename = ['ABRa', int2str(iFile), '.txt'];
Also, if you're really trying to read 1000 files, you should run your loop 1000 times, not twice:
for iFile = 1:1000

MATLAB: export scalars within for loop to text file

I have a large number of text files that I have to read, find the max value for a certain column, and the corresponding time. The for loop for finding these values works fine, but my problem is writing a text file that shows the three variables I need (thisfilename, M, and wavetime) for each iteration of the for loop.
Output_FileName_MaxWaveHeights = ['C:\Users\jl44459\Desktop\QGIS_and_Basement\BASEMENT\Mesh_5_2045\Run_A\','MaxWaveHeights.txt'];
writefile = fopen(Output_FileName_MaxWaveHeights,'a');
dinfo = dir('*.dat');
for K = 1 : length(dinfo)
thisfilename = dinfo(K).name; %just the name of the file
fileID = fopen(thisfilename); %creates numerical ID for the file name
thisdata = textscan(fileID,'%f64%f64%f64%f64%f64%f64%f64',500,'HeaderLines',1); %load just this file
thisdataM = cell2mat(thisdata); %transforms file from cell array to matrix
[M,I] = max(thisdataM(:,5)); %finds max WSE and row it's in
wavetime = 2*(I-1); %converts column of max WSE to time
fprintf(writefile,'%s %8.4f %4.0f \r\n',thisfilename,M,wavetime);
fclose(fileID); %closes file to make space for next one
end
The text file ends up just giving me the values for one iteration instead of all of them. I was able to use displaytable as a workaround, but then I have problems writing "thisfilename", which includes non-numerical characters.
Although I am not able to reproduce the issue with the code provided, a possible solution might be to write to the file outside of the loop and to close the file afterwards:
Output_FileName_MaxWaveHeights = ['C:\Users\jl44459\Desktop\QGIS_and_Basement\BASEMENT\Mesh_5_2045\Run_A\','MaxWaveHeights.txt'];
writefile = fopen(Output_FileName_MaxWaveHeights,'a');
s = [];
dinfo = dir('*.dat');
for K = 1 : length(dinfo)
thisfilename = dinfo(K).name; %just the name of the file
fileID = fopen(thisfilename); %creates numerical ID for the file name
thisdata = textscan(fileID,'%f64%f64%f64%f64%f64%f64%f64',500,'HeaderLines',1); %load just this file
thisdataM = cell2mat(thisdata); %transforms file from cell array to matrix
[M,I] = max(thisdataM(:,5)); %finds max WSE and row it's in
wavetime = 2*(I-1); %converts column of max WSE to time
s = [s, fprintf(writefile,'%s %8.4f %4.0f \r\n',thisfilename,M,wavetime)];
fclose(fileID); %closes file to make space for next one
end
fprintf(writefile,s);
fclose(writefile);
Solved--it was simply me forgetting to close the output file after the loop. Thanks for the help!

Matlab: Renaming files in a folder sequentially

If there are the following files in the folder C:\test\:
file1.TIF, file2.TIF .... file100.TIF
Can MatLab automatically rename them to:
file_0001.TIF, file_0002.TIF, .... file_0100.TIF?
No-loop approach -
directory = 'C:\test\'; %//' Directory where TIFF images are present
filePattern = fullfile(directory, 'file*.tif'); %//' files pattern with absolute paths
old_filename = cellstr(ls(filePattern)) %// Get the filenames
file_ID = strrep(strrep(old_filename,'file',''),'.TIF','') %// Get numbers associated with each file
str_zeros = arrayfun(#(t) repmat('0',1,t), 5-cellfun(#numel,file_ID),'uni',0) %// Get zeros string to be pre-appended to each filename
new_filename = strcat('file_',str_zeros,file_ID,'.TIF') %// Generate new filenames
cellfun(#(m1,m2) movefile(m1,m2),fullfile(directory,old_filename),fullfile(directory,new_filename)) %// Finally rename files with the absolute paths
Edit 1:
For a case when you have the filenames as file27.TIF, file28.TIF, file29.TIF and so on and you would like to rename them as file0001.TIF, file0002.TIF, file0003.TIF and so on respectively, try this -
directory = 'C:\test\'; %//' Directory where TIFF images are present
filePattern = fullfile(directory, 'file*.tif'); %//' files pattern with absolute paths
old_filename = cellstr(ls(filePattern)) %// Get the filenames
file_ID = strrep(strrep(old_filename,'file',''),'.TIF','') %// Get numbers associated with each file
file_ID_doublearr = str2double(file_ID)
file_ID_doublearr = file_ID_doublearr - min(file_ID_doublearr)+1
file_ID = strtrim(cellstr(num2str(file_ID_doublearr)))
str_zeros = arrayfun(#(t) repmat('0',1,t), 4-cellfun(#numel,file_ID),'uni',0) %// Get zeros string to be pre-appended to each filename
new_filename = strcat('file',str_zeros,file_ID,'.TIF') %// Generate new filenames
cellfun(#(m1,m2) movefile(m1,m2),fullfile(directory,old_filename),fullfile(directory,new_filename)) %// Finally rename files with the absolute paths
A slightly more robust method:
dirlist = dir(fullfile(mypath,'*.TIF'));
fullnames = {dirlist.name}; % Get rid of one layer of cell array-ness
[~,fnames,~] = cellfun(#fileparts,fullnames,'UniformOutput',false); % Create cell array of the file names from the output of dir()
fnums = cellfun(#str2double,regexprep(fnames,'[^0-9]','')); % Delete any character that isn't a number, returns it as a vector of doubles
fnames = regexprep(fnames,'[0-9]',''); % Delete any character that is a number
for ii = 1:length(dirlist)
newname = sprintf('%s_%04d.TIF',fnames{ii},fnums(ii)); % Create new file name
oldfile = fullfile(mypath,dirlist(ii).name); % Generate full path to old file
newfile = fullfile(mypath,newname); % Generate full path to new file
movefile(oldfile, newfile); % Rename the files
end
Though this will accomodate filenames of any length, it does assume that there are no numbers in the filename other than the counter at the end. MATLAB likes to throw things into nested cell arrays, so I incorporated cellfun in a couple places to bring things into more manageable formats. It also allows us to vectorize some of the code.

Find duplicates in matlab path

Duplicates in the matlab path are a hassle, because you can not control which one gets executed. A first step to handle duplicates is to find them. How can I find duplicate .m files in my matlab path ?
Well, in itself it's not a herculean task. We juste have to list all .m files in the path and find multiple occurrences of the same file. We can use a mix of the path, what, and unique functions.
function find_duplicate()
P=path;
P=strsplit(P, pathsep());
% mydir='/home/myusername/matlabdir';
% P=P(strncmpi(mydir,P,length(mydir)));
P=cellfun(#(x) what(x),P,'UniformOutput',false);
P=vertcat(P{:});
Q=arrayfun(#(x) x.m,P,'UniformOutput',false); % Q is a cell of cells of strings
Q=vertcat(Q{:});
R=arrayfun(#(x) repmat({x.path},size(x.m)),P,'UniformOutput',false); % R is a cell of cell of strings
R=vertcat(R{:});
[C,ia,ic]=unique(Q);
for c=1:numel(C)
ind=strcmpi(C{c},Q);
if sum(ind)>1
fprintf('duplicate %s at paths\n\t',C{c});
fprintf('%s\n\t',R{ind});
fprintf('\n');
end
end
end
Rather than handling the complete Matlab path, one can restrict the search for duplicates to one's own folder. To do that, just uncomment the third line and replace the directory name by one of your choice.
To analyze a given folder (recursively), you can proceed as follows.
folder = 'C:\Users\Luis\Desktop'; %// folder to be analyzed
[ success files id ] = fileattrib(['.' filesep '*']); %// this is recursive
[fullNames{1:numel(files)}] = deal(files.Name);
isMFile = cellfun(#(s) all(s(end-1:end)=='.m'), fullNames);
fullNames = fullNames(isMFile); %// keep only m-files
F = numel(fullNames);
start = cellfun(#(s) find(s==filesep,1,'last'), fullNames);
names = arrayfun(#(k) fullNames{k}(start(k)+1:end), 1:F, 'uni', 0); %// file name
[ii jj] = ndgrid(1:F); %// generate all pairs
equal = arrayfun(#(n) strcmp(names{ii(n)},names{jj(n)}), 1:F^2); %// test each
%// pair of files
equal = reshape(equal,F,F) - eye(F); %// equality with oneself doesn't count
isDuplicate = any(equal); %// it is a duplicate if it has some equal file
duplicates = fullNames(isDuplicate); %// cell array with full names of duplicates
To test the whole path, use the above code in a loop over all folders in the path. You can do it along the following lines (I haven't tested it, as I don't have the strsplit function):
p = path;
p = strsplit(p,';');
duplicates = {};
for kk = numel(p)
folder = p{kk};
[ success files id ] = fileattrib(['.' filesep '*']);
[fullNames{1:numel(files)}] = deal(files.Name);
isMFile = cellfun(#(s) all(s(end-1:end)=='.m'), fullNames);
fullNames = fullNames(isMFile);
F = numel(fullNames);
start = cellfun(#(s) find(s==filesep,1,'last'), fullNames);
names = arrayfun(#(k) fullNames{k}(start(k)+1:end), 1:F, 'uni', 0);
[ii jj] = ndgrid(1:F);
equal = arrayfun(#(n) strcmp(names{ii(n)},names{jj(n)}), 1:F^2);
equal = reshape(equal,F,F) - eye(F);
isDuplicate = any(equal);
duplicates = {duplicates, fullNames(isDuplicate)}; %// add previous ones
end

Subset folder contents Matlab

I have about 1500 images within a folder named 3410001ne => 3809962sw. I need to subset about 470 of these files to process with Matlab code. Below is the section of code prior to my for loop which lists all of the files in a folder:
workingdir = 'Z:\project\code\';
datadir = 'Z:\project\input\area1\';
outputdir = 'Z:\project\output\area1\';
cd(workingdir) %points matlab to directory containing code
files = dir(fullfile(datadir, '*.tif'))
fileIndex = find(~[files.isdir]);
for i = 1:length(fileIndex)
fileName = files(fileIndex(i)).name;
Files also have ordinal directions attached (e.g. 3410001ne, 3410001nw), however, not all directions are associated with each root. How can I subset the folder contents to include 470 of 1500 files ranging from 3609902sw => 3610032sw? Is there a command where you can point Matlab to a range of files in a folder, rather than the entire folder? Thanks in advance.
Consider the following:
%# generate all possible file names you want to include
ordinalDirections = {'n','s','e','w','ne','se','sw','nw'};
includeRange = 3609902:3610032;
s = cellfun(#(d) cellstr(num2str(includeRange(:),['%d' d])), ...
ordinalDirections, 'UniformOutput',false);
s = sort(vertcat(s{:}));
%# get image filenames from directory
files = dir(fullfile(datadir, '*.tif'));
files = {files.name};
%# keep only subset of the files matching the above
files = files(ismember(files,s));
%# process selected files
for i=1:numel(files)
fname = fullfile(datadir,files{i});
img = imread(fname);
end
Something like this maybe could work.
list = dir(datadir,'*.tif'); %get list of files
fileNames = {list.name}; % Make cell array with file names
%Make cell array with the range of wanted files.
wantedNames = arrayfun(#num2str,3609902:3610032,'uniformoutput',0);
%Loop through the list with filenames and compare to wantedNames.
for i=1:length(fileNames)
% Each row in idx will be as long as wantedNames. The cells will be empty if
% fileNames{i} is unmatched and 1 if match.
idx(i,:) = regexp(fileNames{i},wantedNames);
end
idx = ~(cellfun('isempty',idx)); %look for unempty cells.
idx = logical(sum(,2)); %Sum each row