I'm trying to loop through non-hidden files in a dir and add them to a cell but for some reason it still preserves the indexing of the hidden files.
Number of non-hidden files in png_dir_path = 25
listing = dir(png_dirpath);
ecell = {};
for i=1:length(listing)
name = listing(i).name
if ~strncmp(name, '.', 1) % No files starting with '.'
disp(listing(i).name)
ecell{i} = fullfile(png_dirpath,listing(i).name);
end
end
When I run the above, I get an ecell of size 1x28 but the disp() returns only the hidden filenames. Why is it that when adding the filenames to the cell, it also adds the '.', '..' and '.DS_Store' ?
Thank you!!
Contents of png_dirpath
MBP:cartoon_png$ ls
car1.png car12.png car15.png car18.png car20.png car23.png car3.png car6.png car9.png
car10.png car13.png car16.png car19.png car21.png car24.png car4.png car7.png
car11.png car14.png car17.png car2.png car22.png car25.png car5.png car8.png
Output of script:
>> load_cartoon
name =
.
name =
..
name =
.DS_Store
name =
car1.png
car1.png
name =
car10.png
car10.png
name =
car11.png
car11.png
name =
car12.png
car12.png
name =
car13.png
car13.png
name =
car14.png
car14.png
name =
car15.png
car15.png
name =
car16.png
car16.png
name =
car17.png
car17.png
name =
car18.png
car18.png
name =
car19.png
car19.png
name =
car2.png
car2.png
name =
car20.png
car20.png
name =
car21.png
car21.png
name =
car22.png
car22.png
name =
car23.png
car23.png
name =
car24.png
car24.png
name =
car25.png
car25.png
name =
car3.png
car3.png
name =
car4.png
car4.png
name =
car5.png
car5.png
name =
car6.png
car6.png
name =
car7.png
car7.png
name =
car8.png
car8.png
name =
car9.png
car9.png
As you can see in the above output of the script, the first row in name is with hidden files and the 2nd row is without hidden files.
Mad Physicist's answer is correct as to why you are having that issue.
However, it looks like there is a much simpler way to just get a listing of PNGs in a directory if that is your end goal.
listing = dir(fullfile(png_dirpath,'*.png'));
ecell = {listing.name};
No for loop required or directory checking.
The problem is most likely that you are moving the index into ecell in lockstep with your index in ls. Unless all your hidden files are at the end of the listing, ecell will be the same length as ls. You can use #LuisMendo's suggestion to remove the lockstep:
listing = dir(png_dirpath);
ecell = {};
for item = listing'
if item.name(1) == '.'
ecell{end + 1} = fullfile(png_dirpath, item.name);
end
end
Part of the problem is that you are basing your conclusion that the hidden files are still present on the fact that ecell is 28 elements long. If you had looked at the contents, you would have realized that your algorithm is almost correct. Debugging is a learned skill. It is very easy to learn how to look (you had the right idea with the printouts), but it is very difficult to learn where to look.
Related
I have a folder containing a series of data with file names like this:
abc1
abc2
abc3
bca1
bca2
bca3
bca4
bca5
cba1
... etc
My goal is to load all the relevant files for each file name, so all the "abc" files, and plot them in one graph. Then move on to the next file name, and do the same, and so forth. Is there a way to do this?
This is what I currently have to load and run through all the files, grab the data in them and get their name (without the .mat extension) to be able to save the graph with the same filename.
dirName = 'C:\DataDirectory';
files = dir( fullfile(dirName,'*.mat') );
files = {files.name}';
data = cell(numel(files),1);
for i=1:numel(files)
fname = fullfile(dirName,files{i});
disp(fname);
files{i} = files{i}(1:length(files{i})-4);
disp(files{i});
[Rest of script]
end
You already found out about the cool features of dir, and have a cell array files, which contains all file names, e.g.
files =
'37abc1.mat'
'37abc2.mat'
'50bca1.mat'
'50bca2.mat'
'1cba1.mat'
'1cba2.mat'
The main task now is to find all prefixes, 37abc, 50bca, 1cba, ... which are present in files. This can be done using a regular expression (regexp). The Regexp Pattern can look like this:
'([\d]*[\D]*)[\d]*.mat'
i.e. take any number of numbers ([\d]*), then any number of non-numeric characters ([\D]*) and keep those (by putting that in brackets). Next, there will be any number of numeric characters ([\d]*), followed by the text .mat.
We call the regexp function with that pattern:
pre = regexp(files,'([\d]*[\D]*)[\d]*.mat','tokens');
resulting in a cell array (one cell for each entry in files), where each cell contains another cell array with the prefix of that file. To convert this to a simple not-nested cell array, we call
pre = [pre{:}];
pre = [pre{:}];
resulting in
pre =
'37abc' '37abc' '50bca' '50bca' '1cba' '1cba'
To remove duplicate entries, we use the unique function:
pre = unique(pre);
pre =
'37abc' '50bca' '1cba'
which leaves us with all prefixes, that are present. Now you can loop through each of these prefixes and apply your stuff. Everything put together is:
% Find all files
dirName = 'C:\DataDirectory';
files = dir( fullfile(dirName,'*.mat') );
files = {files.name}';
% Find unique prefixes
pre = regexp(files,'([\d]*[\D]*)[\d]*.mat','tokens');
pre = [pre{:}]; pre = [pre{:}];
pre = unique(pre);
% Loop through prefixes
for ii=1:numel(pre)
% Get files with this prefix
curFiles = dir(fullfile(dirName,[pre{ii},'*.mat']));
curFiles = {curFiles.name}';
% Loop through all files with this prefix
for jj=1:numel(curFiles)
% Here the magic happens
end
end
Sorry, I misunderstood your question, I found this solution:
file = dir('*.mat')
matching = regexp({file.name}, '^[a-zA-Z_]+[0-9]+\.mat$', 'match', 'once'); %// Match once on file name, must be a series of A-Z a-z chars followed by numbers.
matching = matching(~cellfun('isempty', matching));
str = unique(regexp(matching, '^[a-zA-Z_]*', 'match', 'once'));
str = str(~cellfun('isempty', str));
group = cell(size(str));
for is = 1:length(str)
ismatch = strncmp(str{is}, matching, length(str{is}));
group{is} = matching(ismatch);
end
Answer came from this source: Matlab Central
I have a folder containing 9 .htk files. I need to use "dir", and then "readhtk" in a loop to import them to MATLAB, but DIR appears to give 10 files instead of 9! here is my code:
htkfiles = dir('/Users/Desktop/Acsegment/mfcdir/*.htk');
nhtkfiles = length(htkfiles); % 10!!! It should be 9 tough!
data = cell(nhtkfiles,2);
for k = 1:nhtkfiles
b(k,1) = strcat({'/Users/Desktop/Acsegment/mfcdir/'},{htkfiles(k,1).name});
eval(['data{k,1} = readhtk(b{k,1});']);
end
When looking at the filenames in htkfiles, I have them like this:
htkfiles(1,1).name = '.htk'
htkfiles(2,1).name = 'fadg0_si1279.htk'
htkfiles(3,1).name = 'fadg0_si1909.htk'
htkfiles(4,1).name = 'fadg0_si649.htk'
htkfiles(5,1).name = 'fadg0_sx109.htk'
htkfiles(6,1).name = 'fadg0_sx19.htk'
htkfiles(7,1).name = 'fadg0_sx199.htk'
htkfiles(8,1).name = 'fadg0_sx289.htk'
htkfiles(9,1).name = 'fadg0_sx379.htk'
htkfiles(10,1).name = 'faks0_si943.htk'
Comparing to what I see in that folder, the first file is not supposed to be there! Anyone got any ideas why Im getting one extra file?
As mentioned in the comments: the dir command actually works properly, there just happens to be a hidden file.
These files starting with a dot could be removed from your list like so:
d=dir;
d(strncmp({d.name},'.',1))=[];
I have a directory that contains 200 jpeg images. What I want is to rename all these images. So how can I rename all my images at the same time. for example I want to rename the first image to "hello1", "hello2" for the second, "hello3" for the third....>"hello200" for the 200.
Below you can find my code:
maximagesperdir = inf;
directory='imagess';
dnames = {directory};
fprintf('Reading images...');
cI = cell(1,1);
c{1} = dir(dnames{1});
if length(c{1})>0,
if c{1}(1).name == '.',
c{1} = c{1}(4:end);
end
end
if length(c{1})>maximagesperdir,
c{1} = c{1}(1:maximagesperdir);
end
cI{1} = cell(length(c{1}),1);
for j = 1:length(c{1}),
cI{1}{j} = double(imread([dnames{1} '/' c{1}(j).name]))./255;
end
fprintf('done.\n');
Here is some code to rename all the files in the current directory, the code you showed appears to read and not rename.
fnames = dir('*.jpg');
for i = 1:length(fnames)
old_name = fnames(i).name;
new_name = sprintf('hello%d.jpg', i);
movefile(old_name, new_name)
end
If you're just looking to rename the files and not to perform an operation on the images and then rename, there's always the total commander program which is a useful little thing to have. You select all the files and by using ctrl+m you select the way by which you would like to rename them (date, name, etc). Very simple if you're looking to perform the renaming operation scarcely. I'm just saying...
I am currently using the following code to select a file and add its path to a text box.
Dim objDialog As Object
Set objDialog = Application.FileDialog(3)
With objDialog
.AllowMultiSelect = False
.Show
If .SelectedItems.Count = 0 Then
MsgBox "No file selected."
Else
Me.FileNameTextBox = Dir(.SelectedItems(1))
End If
End With
Set objDialog = Nothing
How do I make it so the entire file path is inserted, not just the file name?
.SelectedItems(n) already contains the full path and filename. If what you need is just to separate the name of the file from its path, instead of using the Dir function you could use something like this:
Me.FileNameTextBox = Mid$(.SelectedItems(1), InStrRev(.SelectedItems(1), "\") + 1)
Me.PathTextBox = Left$(.SelectedItems(1), InStrRev(.SelectedItems(1), "\"))
Hope this helps!
you need to remove the dir() part, EG....
Me.FileNameTextBox = .SelectedItems(1)
Hi there I'm currently trying to find a way to save 2 variables from my workspace into a file. I want the file name to be put together using the original and the current date.
I only want the max value from the variables so:
max(streaking)
and
max(tap_total)
The original file name is:
3_FM001_02_05460$BandP$64_24000_FWD_1x1_PRI_PRI_PRI_PRI_15_17_ActivePixelMeans.csv
The only portion of this original file name that I would like to use is:
3_FM001_02_05460$BandP$64_24000_FWD_1x1
These can be saved in a text file or spreadsheet, it doesnt matter.
An example of the new file name would be something like this:
3_FM001_02_05460$BandP$64_24000_FWD_1x1_7-26-2012
Also,
If something could be done in the file to display which variable is which, for example:
Streaking: 1.272 % this would come from the variable max(streaking)
Tap_Total: 2.252 % this would come from the varaible max(tap_total)
EDIT:
% Construct a questdlg with three options
choice = questdlg('Would you like to save?', ...
'Save Options', ...
'Yes','No','Cancel','Cancel');
% Handle response
switch choice
case 'Yes'
disp([choice ' processing.'])
save_option = 1;
case 'No'
disp([choice ' processing.'])
save_option = 0;
case 'Cancel'
disp('Canceled.')
save_option = 2;
end
file_to_get = evalin( 'base', 'file_to_get' );
streaking = evalin( 'base', 'streaking' );
tap_total = evalin( 'base', 'tap_total' );
if save_option == 0
elseif save_option == 1
max_streak = max(streaking);
max_tap = max(tap_total);
str_streak = mat2str(max_streak);
str_tap = mat2str(max_tap);
fname = file_to_get;
pruned_fname = regexprep(fname,'_PRI(\w*).(\w*)','');
new_fname = [pruned_fname '_' date '.csv'];
path1 = '\\pfile01thn\bbruffey$\My Documents\analysis data\Banding and Streaking Results';
fid = fopen([path1 new_fname], 'w');
fprintf(fid,['Max Banding: %s\nMax Streaking: %s'],str_tap,str_streak)
fclose(fid);
elseif save_option == 2
end
This would be a great place to use the regexprep command to prune the original filename down.
Example:
fname = '3_FM001_02_05460$BandP$64_24000_FWD_1x1_PRI_PRI_PRI_PRI_15_17_ActivePixelMeans.csv';
pruned_fname = regexprep(fname,'_PRI(\w*).(\w*)','');
pruned_fname =
3_FM001_02_05460$BandP$64_24000_FWD_1x1
Now, a note about the regexprep command I used here. This is specific for the filename you provided here. Since it looks like you want to trim off everything after the the first _PRI I used a tag (\w*) which means any combination of [a-z A-Z _ 0-9] can follow. Notice that since this is a filename there is a . there hence why I added a period in and followed that with another (\w*) to finish out the csv. You can find more info on these sorts of operators here.
Now that you have the pruned_fname you can simply add whatever you want to it. So if you want to add the date in with an underscore to space it just simply do something like this:
new_fname = [pruned_fname '_' date '.csv'];
new_fname =
3_FM001_02_05460$BandP$64_24000_FWD_1x1csv_26-Jul-2012.csv
Now you simply need to open the file to write to it. you might need to append the path to where you want to save it, I'm just going to call it path for now. It would be something like C:\Documents\
fid = fopen([path new_fname], 'w')
Now with the fid you have the id of the file you want to write to. This should be a new file and if it isn't you are going to overwrite the file contents if you do it this way. Just be aware =)
Next you can simply write those first two lines to the file using fwrite fprintf, just to name a few possible functions.
Hopefully that'll get you setup there!