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

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'

댓글을 달려면 로그인하십시오.

 채택된 답변

Image Analyst
Image Analyst 2013년 6월 9일
편집: Image Analyst 2013년 6월 9일
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

Steven
Steven 2013년 6월 11일
편집: Steven 2013년 6월 11일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Kelly Kearney
Kelly Kearney 2013년 6월 11일
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

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.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Characters and Strings에 대해 자세히 알아보기

태그

질문:

2013년 6월 9일

편집:

2016년 5월 24일

Community Treasure Hunt

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

Start Hunting!

Translated by