Putting files with numeral string names into numeric order

I am trying to sort the order of some experiment files in a directory. The software package that generates the files uses internally generated file names. There are a total of 50 files. The file name comes up something like 'eight00000.T000.D000.P001.H001.CFD.txt. I know that the directory command 'dir' will produce a list of files in the order of 'eight000000','eighteen000000','eleven000000','fifteen000000' and so on. I need to put the files into a numeric order, so 'zero','one','two','three' but be able to reverse the sort order.
I have tried using regexp() and sort () without success.
Any thoughts?

3 Comments

can you give a sample of data you want to sort
This is what the sample data would be, individual files in a single directory:
eight00000.T000.D000.P001.H001.CFD.txt eighteen.T000.D000.P001.H001.CFD.txt eleven.T000.D000.P0001.H001.CFD.txt fifteen.T000.D000.P0001.H001.CFD.txt five.T000.D000.P0001.H001.CFD.txt
They need to be put into numerical order.
This is trivial to implement with my FEX submission words2num:
>> C = {'eight00000.T000.D000.P001.H001.CFD.txt'; 'eighteen.T000.D000.P001.H001.CFD.txt'; 'eleven.T000.D000.P0001.H001.CFD.txt'; 'fifteen.T000.D000.P0001.H001.CFD.txt'; 'five.T000.D000.P0001.H001.CFD.txt'};
>> [~,idx] = sort(cellfun(@words2num,C));
>> C(idx)
ans =
'five.T000.D000.P0001.H001.CFD.txt'
'eight00000.T000.D000.P001.H001.CFD.txt'
'eleven.T000.D000.P0001.H001.CFD.txt'
'fifteen.T000.D000.P0001.H001.CFD.txt'
'eighteen.T000.D000.P001.H001.CFD.txt'

Sign in to comment.

 Accepted Answer

I don't know how many these go up to, but assuming it's only fifty or so, I'd just call dir for each word and concatenate all the results. Sure it's 50 lines of code but that's not many and it's easy and straightforward. You can just toss all the lines into a function or something - no big deal and simpler than trying to use regexp or sort (as you already know).
folder = pwd; % Can be whatever you want.
files = dir(fullfile(folder, 'one*.*'))
files = [files; dir(fullfile(folder, 'two*.*'))];
files = [files; dir(fullfile(folder, 'three*.*'))];
files = [files; dir(fullfile(folder, 'four*.*'))];
files = [files; dir(fullfile(folder, 'five*.*'))];

2 Comments

I implemented the code as you have it. The answer is close, the only problem is that if there are two words that are close together then the file search fails, i.e. four and fourteen, six and sixteen and so on. There is also a tendency to locate the same file two times, so sixteen will show up again around fourteen and fifteen. An example of the code output is below.
I am thinking the problem has to do with how fullfile() looks for file names in a directory.
Any thoughts?
'zero000000.T000.D000.P002.H001.CFD.txt'
'one000000.T000.D000.P002.H001.CFD.txt'
'two000000.T000.D000.P002.H001.CFD.txt'
'three000000.T000.D000.P002.H001.CFD.txt'
'four000000.T000.D000.P002.H001.CFD.txt'
'fourteen000000.T000.D000.P002.H001.CFD.txt'
'five000000.T000.D000.P002.H001.CFD.txt'
'six000000.T000.D000.P002.H001.CFD.txt'
'sixteen000000.T000.D000.P002.H001.CFD.txt'
You're right - I didn't think of that. I don't have time now to fix it. Try Kelly's suggestion in the meantime.

Sign in to comment.

More Answers (1)

How about something like this?
files = dir('*.txt');
numname = regexp({files.name}, '^[a-z]*', 'match', 'once');
allnum = {'zero', 'one', 'two', 'three'}; % etc
[tf, loc] = ismember(numname, allnum);
[blah, isrt] = sortrows([loc' (1:length(files))']);
{files(isrt).name}'
I don't actually have Matlab running right now so I haven't tested this and it probably has some typos, but the basic idea should work.

3 Comments

It does work but to a point. The regexp() is unable to recognize the hyphen that occurs with numbers over nineteen, so twenty and above do not order correctly. There is a sample below. The variable 'numname' reads out twenty for each file name over twenty, in each cell. This is also true for thirty, or forty.
I am guessing two uses of regexp() are required, one to deal with values under twenty, and one to deal with values twenty through fifty.
'eighteen000000.T000.D000.P002.H001.CFD.txt'
'nineteen000000.T000.D000.P002.H001.CFD.txt'
'twenty-eight000000.T000.D000.P002.H001.CFD.txt'
'twenty-five000000.T000.D000.P002.H001.CFD.txt'
'twenty-four000000.T000.D000.P002.H001.CFD.txt'
'twenty-nine000000.T000.D000.P002.H001.CFD.txt'
Just need to alter the regular expression a bit. I also altered the code a bit so it doesn't assume anything about the initial order of files.
files = {...
'eight00000.T000.D000.P001.H001.CFD.txt'
'eighteen.T000.D000.P001.H001.CFD.txt'
'eleven.T000.D000.P0001.H001.CFD.txt'
'fifteen.T000.D000.P0001.H001.CFD.txt'
'five.T000.D000.P0001.H001.CFD.txt'
'twenty-eight000000.T000.D000.P002.H001.CFD.txt'
'twenty-five000000.T000.D000.P002.H001.CFD.txt'
'twenty-four000000.T000.D000.P002.H001.CFD.txt'
'twenty-nine000000.T000.D000.P002.H001.CFD.txt'};
[srt, order1] = sort(files); % sorted alphanumerically
wordnum = {'one', 'two', 'three', 'four', 'five', 'six', 'seven', ...
'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', ...
'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', ...
'nineteen', 'twenty', 'twenty-one', 'twenty-two', ...
'twenty-three', 'twenty-four', 'twenty-five', 'twenty-six', ...
'twenty-seven', 'twenty-eight', 'twenty-nine', 'thirty'};
filewnum = regexp(files, '[A-Za-z\-]*', 'match', 'once');
[tf, loc] = ismember(filewnum, wordnum);
[srt, order2] = sortrows([loc order1]);
sortedfiles = files(order2)
Bingo, that does the job. Thank you very much for your help.

Sign in to comment.

Categories

Tags

Asked:

on 9 Jun 2013

Edited:

on 24 May 2016

Community Treasure Hunt

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

Start Hunting!