-1

I'm trying to access all of the files with a certain file extension from a cell array I have created on MATLAB, but I'm unsure how to do this. Furthermore, I need to be able to make this a variable input. ie so that when I call my function, I can input different file extensions to access different files which correspond to the inputted file extension.

Any help would be greatly appreciated!!

2 Answers2

1

Using fileparts or regexp would be easiest...

% mock data
files = {'a.txt', 'b.png', 'c.txt', 'd.txt.pdf'}; % note d is actually a .pdf file
target = '.txt';

The 3rd output of fileparts is the file extension, so

% option 1 - fileparts
[~,~,ext] = cellfun( @fileparts, files, 'uni', 0 );
files = files( strcmp( target, ext ) );

The regexp option is more robust than strfind because you can ensure the extension is at the end of the string

% option 2 - regexp ('$' to specify end of string)
files = files( ~cellfun( @isempty, regexp( files, [target, '$'], 'once' ) ) );
Wolfie
  • 27,562
  • 7
  • 28
  • 55
0

You can simply use strfind to find the extension of interest within your filename, put that inside an anonymous function, and use cellfun to let this anonymous function work on each of your cell array elements.

Please have a look at the following code snippet:

% Files cell array
files = {
  'text1.txt',
  'text2.txt',
  'image1.png',
  'image2.jpg',
  'audio1.mp3',
  'audio2.mp3'
}

% Extension of interest
ext = 'txt';

% Use strfind operation in cellfun
temp = cellfun(@(x) ~isempty(strfind(x, ['.' ext])), files, 'UniformOutput', false)

% Combine outputs, and find proper indices
idx = find([temp{:}])

% Get files with extension of interest
filesExt = files(idx)

% Get files with extension of interest as one-liner 
% (for the Octave users, where the syntactic sugar for {:} is available)
filesExt = files(find([cellfun(@(x) ~isempty(strfind(x, ['.' ext])), files, 'UniformOutput', false){:}]))

And, this is the output:

files =
{
  [1,1] = text1.txt
  [2,1] = text2.txt
  [3,1] = image1.png
  [4,1] = image2.jpg
  [5,1] = audio1.mp3
  [6,1] = audio2.mp3
}

temp =
{
  [1,1] = 1
  [2,1] = 1
  [3,1] = 0
  [4,1] = 0
  [5,1] = 0
  [6,1] = 0
}

idx =
   1   2

filesExt =
{
  [1,1] = text1.txt
  [2,1] = text2.txt
}

filesExt =
{
  [1,1] = text1.txt
  [2,1] = text2.txt
}

Since I'm currently on Octave, I can't guarantee the one-liner to work on MATLAB. Maybe, someone can please confirm. Anyway, the step-by-step solution should work as intended.

Hope that helps!


EDIT: As Wolfie points out in his answer, "double file extensions" like x.txt.png might cause trouble using this approach.

HansHirse
  • 18,010
  • 10
  • 38
  • 67
  • The one-liner isn't MATLAB compatible, you need the intermediate variable for the `{:}` operator. – Wolfie Sep 06 '19 at 09:16
  • @Wolfie That's exactly, what I had in mind, but I wasn't sure, if that might've been already added to MATLAB. – HansHirse Sep 06 '19 at 09:17
  • You can [use `regexp`](https://stackoverflow.com/a/57819094/3978545) for a one-liner if it's important – Wolfie Sep 06 '19 at 09:18