MATLAB Answers

Seeking a little clarification on using sprintf with %d and formatSpec etc. to load similar *.MAT filenames that only differ in name by number.

6 views (last 30 days)
Hi,
I have previously written code to successfully load multiple *.MAT files from the directory that were named "Position01.mat ... Position10.mat" using ..
NumFiles = 10;
AudioCell = cell(2, NumFiles);
for k = 1: NumFiles;
Position = sprintf('Position%02d.mat', k);
AudioCell{1,k} = importdata(Position);
AudioCell{2,k} = Position;
end
I want to do the same for a group of files named "Band200Hz.mat", "Band400Hz.mat" ... by octave band to ... "Band12000Hz.mat" and I've tried to specify the filename format in a few different ways, but not been able to find the symbol(s) that works. The documentation on format specifiers isn't necessarly too clear or easy to understand for me. I think the biggest complication I (think I) face is that there isn't a ocnsistent number of different digits in each file; i.e., some have 3, like 'Band400Hz.mat' up to five as with 'Band20000Hz', so can't specify in a similar way to the first example by simply adding 'Hz' to the end, after the number specifier. Thusly ...
NumBands = 8;
MasterCell = cell(2, NumBands);
for k = 1 : NumBands
Band = sprintf('Band%02dHz.mat', k);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
A "brute force" workaround would be to put the octave band filtered signal *.MAT files into their own directory and use ...
dir('*.mat')
But I'd prefer to avoid that.
Any help or helpful links regarding this kind of format specification would be greatly appreciated. If there are any entirely different approaches, I'm interested to find out about those too. Thanks a lot!

  0 Comments

Sign in to comment.

Accepted Answer

per isakson
per isakson on 25 Oct 2020
Edited: per isakson on 25 Oct 2020
Less brute
sad = dir( fullfile( root_folder, '**', 'Band*Hz.mat') );
However, this assumes that you want to read all files under the root, which matches the pattern.
Or your approach
for k = 1 : [ 2.^[1:8]*100] % by octave band
sprintf('Band%dHz.mat', k);
...
'Band20000Hz' is not in my sequence, but should it be?
Then I would use load() rather than importdata() (?)
EDIT:
With names like "Band3150Hz.mat" and "Band20000Hz.mat" use
for k = 1 : [200,400,..,3150,20000]

  4 Comments

Show 1 older comment
Peter Beringer
Peter Beringer on 25 Oct 2020
The first suggesting looks appealing, and the files are in the same root directory. I hadn't read that star substitution could be used like that.
Band20000Hz.mat is in the sequence. I will try 'load' and see how that goes. Though, I am more or less compying a wonderfully functioning script I've already written, it's just the difference in name format that I want to overcome, and Stephen said it was even simpler than that last script. I'm probably overthinking this.
So I gave this a try ...
for k = 1 : [200,400,800,1600,3150,6300,12500,20000]
Band = sprintf('Band%dHz.mat', k);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
As I tried above, putting the frequencies into the 'for' loop as your edit showed looks like a neat solution, but was unable to load any files. Have I made an obvious mistake and/or missed something silly? But really I'd like to load each file into a cell with its name in the row below, like I've done in previous scripts; which I believe is the better option.
Thanks for your help so far :)
per isakson
per isakson on 25 Oct 2020
Maybe, we should honor Stephen's advice
k = [200,400,800,1600,3150,6300,12500,20000];
MasterCell = cell(2,numel(k));
for jj = 1 : numel(k)
Band = sprintf('Band%dHz.mat', k(jj));
MasterCell{1,jj} = importdata(Band);
MasterCell{2,jj} = Band;
end
This script must be run in the folder of the mat-files.
"but was unable to load any files" What happend, any error message? Hard for us to guess!
"obvious mistake" Your script will create a huge cell array, MasterCell, with the size 2x20000. That counts as a mistake.
Peter Beringer
Peter Beringer on 25 Oct 2020
The error was just that: "Unable to load file" when it got to the first four-digit value.
Thanks for your help.

Sign in to comment.

More Answers (1)

Asad (Mehrzad)  Khoddam
Asad (Mehrzad) Khoddam on 25 Oct 2020
you can use:
sprintf('Band%dHz.mat', k*200);

  6 Comments

Show 3 older comments
Peter Beringer
Peter Beringer on 25 Oct 2020
Sorry. The eight *.MAT files are:
"Band200Hz.mat", "Band400Hz.mat", "Band800Hz.mat", "Band1600Hz.mat", "Band3150Hz.mat". "Band6300Hz.mat" and "Band12000Hz.mat" ...
I used Asad Khoddam's answer this way and it returned the following (attached screenshot) ...
NumBands = 8;
MasterCell = cell(2, NumBands);
for k = 1 : NumBands
Band = sprintf('Band%dHz.mat', k*200);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
Which is why I thought it was only applying to 3 digit labels. And that k * 200 was doing it with 1 * 200 = 200, 2 * 200 = 400, then there's no file name with 600 in it, no 'Band600Hz.mat', so there the 'for' loop stopped.
I'm sorry if I don't understand it all completely, be assured I'm trying my hardest.
Peter Beringer
Peter Beringer on 25 Oct 2020
Exactly, no integer * 200 will equal 3150, so that's what made me think multiplying k by 200 wouldn't work. Why is that logic flawed? And it didn't work, as soon as it went looking for "Band600Hz.mat", it returned the error "Unable to load file".
Please to see that you're editing insults out of your comments ... you'll get to the level of "civility" soon enough.
Thanks for your help!

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by