Matlab - 如何找到任意文件组的最低公共目录?

时间:2016-10-14 00:43:35

标签: matlab

我有一个完整文件名的单元格数组,我想找到存储累积数据有意义的最低公共目录。

以下是测试数据的示例层次结构:

    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');

2 个答案:

答案 0 :(得分:2)

您只需要比较数组中任何路径的第一个d字符 - 例如路径1 - 使用其他路径的第一个d字符。最长的公共基本路径不能比路径1长,并且它不能比路径1和任何其他路径之间的最短公共基路径短。

必须有多种方法可以做到这一点,但简洁的方法是使用strfind来匹配字符串,使用cellfunisempty来检查哪些不匹配:

% 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), '\');