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.
Related
I would like to read text files inside a zip file without unzipping using Matlab
Read the data of CSV file inside Zip File without extracting the contents in Matlab
The suggested above is working and I get list of cells for file.
zipFilename = 'C:\ZippedData.zip';
zipJavaFile = java.io.File(zipFilename);
% Create a Java ZipFile
zipFile = org.apache.tools.zip.ZipFile(zipJavaFile);
% Extract the entries from the ZipFile.
entries = zipFile.getEntries;
cnt = 1;
% Get Zip File Paths
while entries.hasMoreElements
tempObj = entries.nextElement;
file{cnt,1} = tempObj.getName.toCharArray';
cnt = cnt+ 1;
end
% Extract File Name
ind = regexp(file,'textfile.*');
ind = find(~cellfun(#isempty,ind)); % Find Non Empty Cell Index
file = file(ind);
% Create Absolute Path so that Windows consider as Directory
file = cellfun(#(x) fullfile('.',x),file,'UniformOutput',false);
\file1 , .\file2 ,..., .\filen , but them how do I use that in fopen and say textscan? something like fileID = fopen([zipFilename filesep file{1}]); ?.
I am trying to edit 100 .mat files in a folder with no pattern in their names. Each file contains a matrix of size 100-by-10, and I want to convert them to 10-by-10-by-10. How do I go about this?
Provided you have a single matrix in each file, and want to overwrite the original matrix:
listing = dir('*.mat'); % finds all .mat files in your pwd
for ii = 1:numel(listing)
tmp = listing(ii).name;
s = load(tmp); % load a file
Fname = fieldnames(s); % get matrix name
out = reshape(s.(Fname{1}),[10 10 10]); % reshape
save(tmp,'out') % Save, overwriting original
end
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.
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
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