找到.mat文件之间的所有差异

时间:2013-10-02 09:56:22

标签: matlab file diff mat-file

我正在寻找一种方法来列出两个.mat文件之间的差异,这对许多人来说非常有用。

虽然我在任何地方都能想到,但我找不到符合我要求的东西:

  1. 选择2个席子文件
  2. 找出差异
  3. 正确保存
  4. 我最接近的是visdiff。只要我留在matlab中,它就可以让我浏览差异,但是当我保存结果时它只显示我的最高级别。


    以下是我的文件通常如下所示的简化示例:

    a = 6;
    b.c.d = 7;
    b.c.e = 'x';
    save f1
    f = a;
    clear a
    b.c.e = 'y';
    save f2
    visdiff('f1.mat','f2.mat')
    

    如果我点击b,我可以找到差异。但是,如果我运行此操作并使用'file> save',我将无法点击b。因此,我仍然不知道改变了什么。

    注意:我没有Simulink


    因此我的问题是:

    如何在没有Matlab

    的情况下显示2个mat文件之间的所有差异

    以下是我个人认为最适合不同情况的答案:

7 个答案:

答案 0 :(得分:8)

找到没有MATLAB的mat文件之间的所有差异?

您可以找到基于HDF5.mat filesHDF5 Tools之间的差异。

实施例

让我简化您的MATLAB示例并假设您使用

创建两个mat文件
clear ; a = 6 ; b.c = 'hello' ; save -v7.3 f1
clear ; a = 7 ; b.e = 'world' ; save -v7.3 f2

在MATLAB之外使用

h5ls -v -r f1.mat

获取有关f1.mat的数据类型的列表:

Opened "f1.mat" with sec2 driver.
/                        Group
    Location:  1:96
    Links:     1
/a                       Dataset {1/1, 1/1}
    Attribute: MATLAB_class scalar
        Type:      6-byte null-terminated ASCII string
        Data:  "double"
    Location:  1:2576
    Links:     1
    Storage:   8 logical bytes, 8 allocated bytes, 100.00% utilization
    Type:      native double
/b                       Group
    Attribute: MATLAB_class scalar
        Type:      6-byte null-terminated ASCII string
        Data:  "struct"
    Location:  1:800
    Links:     1
/b/c                     Dataset {5/5, 1/1}
    Attribute: H5PATH scalar
        Type:      2-byte null-terminated ASCII string
        Data:  "/b"
    Attribute: MATLAB_class scalar
        Type:      4-byte null-terminated ASCII string
        Data:  "char"
    Attribute: MATLAB_int_decode scalar
        Type:      native int
        Data:  2
    Location:  1:1832
    Links:     1
    Storage:   10 logical bytes, 10 allocated bytes, 100.00% utilization
    Type:      native unsigned short

使用

h5ls -d -r f1.mat

返回存储数据的值:

/                        Group
/a                       Dataset {1, 1}
    Data:
        (0,0) 6
/b                       Group
/b/c                     Dataset {5, 1}
    Data:
        (0,0) 104, 101, 108, 108, 111

数据104, 101, 108, 108, 111代表单词hello,可以通过

查看
h5ls -d -r f1.mat | tail -1 | awk '{FS=",";printf("%c%c%c%c%c \n",$2,$3,$4,$5,$6)}'

您可以获得f2.mat的相同列表,并使用您选择的工具比较两个输出。

比较也直接与HDF5 Tools一起使用。要比较两个文件中的两个数字a,请使用

h5diff -r f1.mat f2.mat /a

将显示值及其差异

dataset: </a> and </a>
size:           [1x1]           [1x1]
position        a               a               difference          
------------------------------------------------------------
[ 0 0 ]          6               7               1              
1 differences found
attribute: <MATLAB_class of </a>> and <MATLAB_class of </a>>
0 differences found

说明

HDF5 Tools中还有一些命令和选项可能有助于解决您的实际问题。

二进制发行版可从The HDF Group用于Linux和Windows。对于OS X,您可以通过MacPorts安装它们。如果需要,还有一个GUI:HDFView

答案 1 :(得分:5)

如果你有simulink,你可以使用Simulink.saveVars生成一个m文件,在执行时在工作区中创建相同的变量:

a = 6;
b.c.d = 7;
b.c.e = 'x';
Simulink.saveVars('f1');
f = a;
clear a
b.c.e = 'y';
Simulink.saveVars('f2');
visdiff('f1.m','f2.m')

如此sctreenshot中所示

enter image description here

请注意,默认情况下,它会将数组中的元素数限制为1000,并且可以将其增加到10000.大于该限制的数组将保存在单独的mat文件中。

UPDATE:从R2014a开始,MATLAB中添加了一个类似于Simulink.saveVars的新函数。见matlab.io.saveVariablesToScript

答案 2 :(得分:4)

这只是答案的一部分,但也许有帮助。

您可以使用gencode,一个Matlab函数,从变量生成Matlab代码,以便运行代码再现变量。你为每个mat文件中的所有变量执行此操作(需要一些编程,但应该可行)并将结果放在不同的.m文件中。

然后使用标准文本比较工具(甚至可能visdiff)来比较.m文件。

答案 3 :(得分:3)

有几种比较XML文件的好工具,我会这样做:

  1. 下载struct2xml.m
  2. 加载两个matfiles
  3. 使用struct2xml
  4. 导出每个
  5. 使用XMLSpy或类似的
  6. 进行比较

答案 4 :(得分:2)

回答小文件,显示所有价值差异

基于@A的建议。 Donda我试图使用gencode为所有内容创建一个变量。

虽然它适用于我的玩具示例,但它很慢并告诉我,我超过了我的真实.mat文件的允许变量数量。

无论如何,对于那些正在寻找适合小文件的人,我会发布这个选项:

wList=who;
for iLoop = 1:numel(wList)
    eval(['generated_' wList{iLoop} '= gencode(' wList{iLoop} ');'])
    for jLoop = 1:numel(eval(['generated_' wList{iLoop}]))
        eval(['generated_' wList{iLoop} '_' num2str(jLoop) '= generated_' wList{iLoop} '(' num2str(jLoop) ');' ])
    end
end

虽然它可能有用,但我觉得这不是最好的方法。

答案 5 :(得分:2)

简单的一般答案,没有显示价值差异

由于我从@BHF,@ Daniel R和@Dennis Jaheruddin的答案中获得的洞察力,我设法找到了一个简单的可扩展解决方案:

[fs1, fs2, er] = comp_struct(load('f1.mat'),load('f2.mat'))

请注意,它适用于包含多个变量的.mat。

这使用Compare Structures - File Exchange submission

答案 6 :(得分:1)

一般答案,不显示价值差异

由于我从@BHF和@Daniel R的答案中获得的洞察力,我设法找到了一个合理可扩展的解决方案。

步骤1:将每个文件中的所有变量保存为单个结构

这使用Save workspace to struct - File Exchange submission

假设您要比较f1.matf2.mat,请执行以下步骤:

clear
load f1
myStruct1 = ws2struct;
save myStruct1 myStruct1 
clear
load f2
myStruct2 = ws2struct;
save myStruct2 myStruct2 
clear                    
load myStruct1
load myStruct2

第2步:比较结构

这使用Compare Structures - File Exchange submission

鉴于您想要比较myStruct1myStruct2,您只需致电:

[fs1, fs2, er] = comp_struct(myStruct1,myStruct2)

我对er中的差异列表的可读性感到非常惊讶,这里是问题中使用的示例的输出:

er =

's2 is missing field a'
's1(1).b(1).c(1).e and s2(1).b(1).c(1).e do not match'

请注意,它不会显示值,从技术角度来看,如果需要显示值差异,则更改m文件可能并不太难。但是,特别是如果有一些大矩阵,我认为这可能会导致输出问题。