我有一个完整文件名的单元格数组,我想找到存储累积数据有意义的最低公共目录。
以下是测试数据的示例层次结构:
C:\Test\Run1\data1
C:\Test\Run1\data2
C:\Test\Run1\data3
C:\Test\Run2\data1
C:\Test\Run2\data2
.
.
.
在Matlab中,路径存储在单元格数组中,如下所示(每次运行共享一行):
filePaths = {...
'C:\Test\Run1\data1','C:\Test\Run1\data2','C:\Test\Run1\data3'; ...
'C:\Test\Run2\data1','C:\Test\Run2\data2','C:\Test\Run2\data3'};
我想编写一个输出公共路径C:\Test\Run1
的例程,以便我可以在那里的新目录中存储相关的图。
C:\Test\Run1\Accumulation_Plots
C:\Test\Run2\Accumulation_Plots
.
.
.
以前,我只关心x-by-2单元格中的两个文件,所以下面的团队工作;然而,strcmp
失去了它的吸引力,因为我不能(AFAIK)立刻索引整个细胞。
d = 1;
while strcmp(filePaths{1}(1:d),filePaths{2}(1:d))
d = d + 1;
end
common_directory = filePaths{1}(1:d-1);
mkdir(common_directory,'Accumulation_Plots');
答案 0 :(得分:2)
您只需要比较数组中任何路径的第一个d
字符 - 例如路径1 - 使用其他路径的第一个d
字符。最长的公共基本路径不能比路径1长,并且它不能比路径1和任何其他路径之间的最短公共基路径短。
必须有多种方法可以做到这一点,但简洁的方法是使用strfind
来匹配字符串,使用cellfun
和isempty
来检查哪些不匹配:
% filePaths should contain at least two paths
filePaths = {...
'C:\Test\Run1\data1','C:\Test\Run1\data2','C:\Test\Run1\data3'; ...
'C:\Test\Run2\data1','C:\Test\Run2\data2','C:\Test\Run2\data3'};
path1 = filePaths{1};
filePaths = filePaths(2:end);
% find longest common left-anchored substring
d = 1;
while ~any(cellfun(@isempty, strfind(filePaths, path1(1:d))))
d = d + 1;
end
% find common base path from substring
[common_directory, ~, ~] = fileparts(path1(1:d));
您的代码离开d
,其中包含路径之间最长公共左锚定子字符串的长度,但这可能比公共基本路径长; fileparts
从该子字符串中提取实际的基本路径。
答案 1 :(得分:2)
As suggested by @nekomatic, I'm posting my comment as an answer.
filePaths = {...
'C:\Test\Run1\data1','C:\Test\Run1\data2','C:\Test\Run1\data3'; ...
'C:\Test\Run2\data1','C:\Test\Run2\data2','C:\Test\Run2\data3'};
% Sort the file paths
temp = sort(filePaths(:));
% Take the first and the last one, and split by '\'
first = strsplit(temp{1}, '\');
last = strsplit(temp{end}, '\');
% Compare them up to the depth of the smallest. Find the 'first N matching values'
sizeMin = min(numel(first), numel(last));
N = find(~[cellfun(@strcmp, first(1:sizeMin), last(1:sizeMin)) 0], 1, 'first') - 1;
% Get the smallest common path
commonPath = strjoin(first(1:N), '\');