14

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

虽然我到处搜索我能想到的,但我没有找到任何符合我要求的东西:

  1. 选择 2 个 mat 文件
  2. 找出差异
  3. 妥善保存它们

我最接近的是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,我可以找到不同之处。但是,如果我运行它并使用“文件>保存”,我将无法单击b. 因此,我仍然不知道发生了什么变化。

注意:我没有 Simulink


因此我的问题是:

如何向没有 Matlab 的人显示 2 个 mat 文件之间的所有差异


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

4

7 回答 7

8

在没有 MATLAB 的情况下查找 mat 文件之间的所有差异?

您可以使用HDF5 工具找到基于HDF5.mat 文件之间的差异。

例子

让我缩短您的 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 工具一起使用。要比较两个文件中的两个数字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 工具中还有一些命令和选项,它们可能有助于解决您的实际问题。

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

于 2013-10-11T19:24:47.060 回答
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')

如本截图所示

在此处输入图像描述

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

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

于 2013-10-02T11:46:18.297 回答
4

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

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

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

于 2013-10-02T10:57:23.157 回答
3

有几个很好的工具可以比较 XML 文件,我会这样处理:

  1. 下载struct2xml.m
  2. 加载两个 matfile
  3. 使用 struct2xml 导出每个
  4. 比较,使用 XMLSpy 或类似的
于 2013-10-16T20:50:04.033 回答
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

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

于 2013-10-02T12:07:34.663 回答
2

简单的一般答案,不显示值差异

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

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

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

这使用比较结构-文件交换提交

于 2016-05-03T09:03:13.430 回答
1

一般答案,不显示值差异

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

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

这使用保存工作区来构造文件交换提交

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

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

第 2 步:比较结构

这使用比较结构 - 文件交换提交

鉴于您想比较myStruct1myStruct2您可以简单地调用:

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

我对差异列表的可读性感到非常惊讶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 文件可能并不难。但是,特别是如果有一些大矩阵,我认为这可能会导致输出有问题。

于 2013-10-18T09:35:49.390 回答