- extList is a cell array of character vectors that contain the user's input list
- nExt is the number of extensions entered
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to ask the user how many file extensions to search for
1 view (last 30 days)
Show older comments
I currently have a script which find files in a folder with a matching string that the user inputs.
I also have code where the user enters the file extensions he wants the script to look for.
ext1 = inputdlg('Please enter file extension #1: **\*. ');
ext2 = inputdlg('Please enter file extension #2: **\*. ');
ext3 = inputdlg('Please enter file extension #3: **\*. ');
fileData = [dir(fullfile(fileLoc,char(ext1))); dir(fullfile(fileLoc,char(ext2))); dir(fullfile(fileLoc,char(ext3)))];
What I want to do instead of ask the user how many different file extensions he wants to look for and then ask for them accordingly.
(e.g. User inputs he wants to search for 5 different file extensions and the script asks for 5)
I'd like to do this instead of just hard-coding in how many file extensions he can search for.
Accepted Answer
Adam Danz
on 13 Sep 2019
Edited: Adam Danz
on 13 Sep 2019
That's too much work (for you and the user). Instead, the user could just list all file extensions in the first dialog, separated by commas. Then you can separate that list into individual extensions.
ext = inputdlg('Please enter file extensions separated by a comma: **\*. Example: txt, csv, ogg');
if ~isempty(ext) %check if user entered anything
% Separate selections
extList = strtrim(strsplit(ext{1},','));
extList(cellfun(@isempty,extList)) = []; % get rid of empties (if any)
nExt = numel(extList); %number of extensions
end
For example, in the inputdlg enter this: txt, csv, ogg, xlsx
If there is a set list of possible file extensions, a better idea would be to use a listbox where the user can merely select from a set of options.
12 Comments
Nom
on 13 Sep 2019
Great response!
I will definitely do it this way.
However, how would I implement this into the dir function?
fileData = dir(fullfile(fileLoc,char(extlist)));
This gives me an error, hence why I was using
fileData = [dir(fullfile(fileLoc,char(ext1))); dir(fullfile(fileLoc,char(ext2))); dir(fullfile(fileLoc,char(ext3)))];
for the three seperate file extensions.
Walter Roberson
on 13 Sep 2019
The easiest way is to loop doing a dir() for each extension and concatenating the results.
Walter Roberson
on 13 Sep 2019
The result of dir() is not characters.
Adam made a small mistake:
for i = 1:nExt
fileData = [fileData; dir(fullfile(fileLoc,extList{i}))];
. . .
end
Notice the change from comma to semi-colon. dir() returns a column vector of struct.
Nom
on 13 Sep 2019
Edited: Nom
on 13 Sep 2019
I inputted ".docx, pdf, txt"
as an example with the following code which Walter edited
for i = 1:nExt
fileData = [fileData; dir(fullfile(fileLoc,extList{i}))];
end
However, this gives an "Undefined function or variable 'fileData'."
If it's worth mentioning, I do have the above code outside of the if statement
Adam Danz
on 13 Sep 2019
That's why you have to include the line below prior to the loop.
fileData = [];
Nom
on 13 Sep 2019
I can't thank you enough,
It works perfectly I love it!
If there's one thing (totally optional), currently the extensions require the user to input " **\*. " before every entry otherwise it will not search the entire file name.
How might I input this into the code so the user doesn't have to?
Again, I really appreciate your help.
Walter Roberson
on 13 Sep 2019
fileData = [];
for i = 1:nExt
fileData = [fileData; dir(fullfile(fileLoc, ['**\*.', extList{i}]))];
end
Note: if you are using **\ then that says to search all subdirectories. In order to know which directory the file was found in, you will need to look at the folder field of the information returned by dir. You can generate the entire list of fully-qualified names by using
fullfile( {fileData.folder}, {fileData.name})
Nom
on 13 Sep 2019
Thank you! Yes I've already implemented it in that exact way,
weirdly enough running this script from a .m file works flawlessly
But when I moved the new code into my app designer's code it gives this error.
Cell contents reference from a non-cell array object.
on this line
extList = strtrim(strsplit(ext{1},','));
Which is pretty confusing because this is the exact code which worked straight from a .m script file.
The app designer's code was functioning with my old way (three file extensions hard coded in)
So I'm not sure why app designer is seeing something differently
Adam Danz
on 13 Sep 2019
Edited: Adam Danz
on 13 Sep 2019
Hmmm, could you show us exactly what's in ext and the result of class(ext)?
[update]
I just embedded the code from my answer into app designer and entered a variety of inputs including several extensions, 1 extension, and empty, and there was no error.
More Answers (2)
Nom
on 13 Sep 2019
Right before
extList = strtrim(strsplit(ext{1},','));
is executed.
K>> ext
ext =
'txt, pdf, docx'
K>> class(ext)
ans =
'char'
Above what I put into the command script
2 Comments
Walter Roberson
on 13 Sep 2019
So somehow ext is a character vector instead of a cell array of char.
As a general fix: after you have called
ext = inputdlg('Please enter file extensions separated by a comma:. Example: txt, csv, ogg: ');
add
ext = cellstr(ext);
Though you might have to check isempty() first.
Adam Danz
on 13 Sep 2019
inputdlg should always return a cell array:
Where is the 'txt, pdf, docx' char array coming from? I can't be the output to inputdlg.
Nom
on 13 Sep 2019
Awesome!
I'm forever in your debt
Works perfectly!
17 Comments
Nom
on 13 Sep 2019
I know I've already asked so much, but I was wondering if there was a way I could have hyperlinks outputted in an excel file.
Currently I have this set up running to output into excel, is there anyway to just make them into hyperlinks by default so I could just click on the file path and have it open directly up?
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(~finalFlag)) ' ';
'Date' 'Size' 'File'};
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024) fullPaths(~finalFlag)];
xlswrite(outputFile,outputData);
Adam Danz
on 13 Sep 2019
Do you want to write a hyperlink to an excel file or do you want to write a hyperlink to the command window that, when selected, opens the excel file?
Nom
on 13 Sep 2019
Straight into an excel file.
So that opening the excel file the file path would be hyper linked so you could just click on it to take you directly to it.
Adam Danz
on 13 Sep 2019
Nom
on 16 Sep 2019
Edited: Nom
on 16 Sep 2019
So what's happening now weirdly is if I enter docx and search for the terms "test1 test2 test3" it works. But if I enter more than just docx e.g. (docx, txt) or even just txt alone. It gives the following error:
Error using horzcat
Dimensions of matrices being concatenated are not consistent.
Error in Testapp/StartButtonPushed (line 109)
stmFileSearch(app,fileLoc,outputFile,rejectFile)
The error occurs on the line below, I've also marked it in the full code I've pasted below.
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024) fullPaths(~finalFlag)];
The code I'm using is below:
tic;
if ~isempty(ext) %check if user entered anything
% Separate selections
ext = cellstr(ext);
extList = strtrim(strsplit(ext{1},','));
extList(cellfun(@isempty,extList)) = []; % get rid of empties (if any)
nExt = numel(extList); %number of extensions
end
fileData = [];
for i = 1:nExt
fileData = [fileData; dir(fullfile(fileLoc, ['**\*.', extList{i}]))];
end
% Get the dates & Sizes
fileDates = {fileData.date}';
fileSizes = [fileData.bytes]';
% Get the full paths
fullPaths = fullfile( {fileData.folder}, {fileData.name});
overallTime = toc;
strinput = char(fil);
tic;
xorString2 = strsplit(strinput);
ignoreFlag2 = ~contains(fullPaths,xorString2,'IgnoreCase',true);
finalFlag = ignoreFlag2;
overallTime2 = toc;
% Create the output
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(~finalFlag)) ' ';
'Date' 'Size' 'File'};
%vvvvvvvvvvvvvvvvvvvv ERROR vvvvvvvvvvvvvvvvvvvvvvvv
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024)]; fullPaths(~finalFlag)];
%^^^^^^^^^^^^^^^^^^^^ ERROR ^^^^^^^^^^^^^^^^^^^^^^^
xlswrite(outputFile,outputData);
Adam Danz
on 16 Sep 2019
Unfortunately I could not run all of your code because I don't have the value for "fil". I can suggestion some areas to look at.
xlswrite(outputFile,outputData);
As you can read here, the 2nd input to xlswrite() is a "two-dimensional numeric, character array, or string array, or, if each cell contains a single element, a cell array". It doesn't look like that is the case in your code.
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024)
I'm not sure what's happening here (above). it looks like you're horizontally concatenating two things that are different sizes.
I can't easily troubleshoot if I can't reproduce the problem so if you still need some help, makes sure we have code and data so that we can step through each line of your code.
Nom
on 16 Sep 2019
Edited: Nom
on 16 Sep 2019
I apologize,
fil is what the user puts to "filter" the file names with a given string in this case the fil should be test1 test2 test3, so that program will search for files which have matching strings in the folder "fileLoc"
What I found weirdly is that the program works if I remove the header of the file path printed
fullPaths = strrep(fullPaths,fileLoc,'')'; % Remove the header path
I have no clue why this makes it work, but I need the file headers to show up so I may hyper link them
Scratch that, it doesn't work, I encounter the same problem :(
Nom
on 16 Sep 2019
I just can't understand why inputting docx, is the only extension which works. Everything else even on its own e.g.(txt) gives that error
Adam Danz
on 16 Sep 2019
Ok, since this section below is what's causing the problem, could you run the code up to that point and then save all of the needed variables to a mat file, and then attach that file.
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(~finalFlag)) ' ';
'Date' 'Size' 'File'};
%vvvvvvvvvvvvvvvvvvvv ERROR vvvvvvvvvvvvvvvvvvvvvvvv
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024)]; fullPaths(~finalFlag)];
%^^^^^^^^^^^^^^^^^^^^ ERROR ^^^^^^^^^^^^^^^^^^^^^^^
So I need
- fileLoc
- overallTime
- overallTime2
- fileFlag
That way I can run that section.
Nom
on 16 Sep 2019
Edited: Nom
on 16 Sep 2019
Ok so this code below works but I have one major issue
% Get the files
tic;
if ~isempty(ext) %check if user entered anything
% Separate selections
ext = cellstr(ext);
extList = strtrim(strsplit(ext{1},','));
extList(cellfun(@isempty,extList)) = []; % get rid of empties (if any)
nExt = numel(extList); %number of extensions
end
fileData = [];
for i = 1:nExt
fileData = [fileData; dir(fullfile(fileLoc, ['**\*.', extList{i}]))];
end
% Get the dates & Sizes
fileDates = {fileData.date}';
fileSizes = [fileData.bytes]';
% Get the full paths
fullPaths = fullfile( {fileData.folder}, {fileData.name});
%NEW LINE ADDED BELOW
fullPaths = strrep(fullPaths,fileLoc,'')'; % Remove the header path
%NEW LINE ADDED ABOVE
% h1 = ['=HYPERLINK('];
% h2 = fileLoc;
% h3 = ')';
% strcomb = strcat(h1,h2,h3);
% fullPaths = strrep(fullPaths,fileLoc,strcomb);
overallTime = toc;
strinput = char(fil);
tic;
xorString2 = strsplit(strinput);
ignoreFlag2 = ~contains(fullPaths,xorString2,'IgnoreCase',true);
finalFlag = ignoreFlag2;
overallTime2 = toc;
% Create the output
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(~finalFlag)) ' ';
'Date' 'Size (kb)' 'File'};
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024) fullPaths(~finalFlag)];
xlswrite(outputFile,outputData);
% Create the rejected output
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(finalFlag)) ' ';
'Date' 'Size (kb)' 'File'};
fileDates(finalFlag) num2cell(fileSizes(finalFlag) ./1024) fullPaths(finalFlag)];
xlswrite(rejectFile,outputData);
msgbox('Operation Completed');
I have this line in there which removes the file path's header e.g. ("C:\Users\User1\Desktop\Search Script\1.xlsx" becomes just 1.xlsx.
fullPaths = strrep(fullPaths,fileLoc,'')';
anyway to avoid this, I just want to be able to add hyper links in the future, and for that i require the full file path
Nom
on 16 Sep 2019
It's so weird, it gives the
Error using horzcat
Dimensions of matrices being concatenated are not consistent.
Error in Testapp/StartButtonPushed (line 109)
stmFileSearch(app,fileLoc,outputFile,rejectFile)
if I comment it out
Nom
on 16 Sep 2019
Okay guys, I solved the problem by just adding
fullPaths = strcat(fileLoc,fullPaths);
right before
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(~finalFlag)) ' ';
'Date' 'Size (kb)' 'File'};
fileDates(~finalFlag) num2cell(fileSizes(~finalFlag) ./1024) fullPaths(~finalFlag)];
I'm terribly sorry for wasting everyone's time,
I've spent four hours trying to fix this myself.
Adam Danz
on 17 Sep 2019
I'm not sure how that solved the error you were getting.
Notice at the end of this line you transpose the array.
fullPaths = strrep(fullPaths,fileLoc,'')'; % Remove the header path
% HERE ^
So when you comment that out, fullPaths remains as a row-cell-array.
That causes the error when you try to horizontally concatenate the bottom line below.
outputData = [{'Starting Path:' fileLoc ' ';
'Time to Execute:' [sprintf('%.2f',overallTime+overallTime2) 's'] ' ';
'File Count:' num2str(sum(finalFlag)) ' ';
'Date' 'Size (kb)' 'File'};
fileDates(finalFlag) num2cell(fileSizes(finalFlag) ./1024) fullPaths(finalFlag)];
%|___column array___| {______________Column array_________| |____Row array______|
See Also
Categories
Find more on File Operations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)