我正在寻找一种方法来列出两个.mat文件之间的差异,这对许多人来说非常有用。
虽然我在任何地方都能想到,但我找不到符合我要求的东西:
我最接近的是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文件之间的所有差异以下是我个人认为最适合不同情况的答案:
答案 0 :(得分:8)
您可以找到基于HDF5的.mat files与HDF5 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中所示
请注意,默认情况下,它会将数组中的元素数限制为1000,并且可以将其增加到10000.大于该限制的数组将保存在单独的mat文件中。
UPDATE:从R2014a开始,MATLAB中添加了一个类似于Simulink.saveVars
的新函数。见matlab.io.saveVariablesToScript
答案 2 :(得分:4)
这只是答案的一部分,但也许有帮助。
您可以使用gencode,一个Matlab函数,从变量生成Matlab代码,以便运行代码再现变量。你为每个mat文件中的所有变量执行此操作(需要一些编程,但应该可行)并将结果放在不同的.m文件中。
然后使用标准文本比较工具(甚至可能visdiff
)来比较.m文件。
答案 3 :(得分:3)
有几种比较XML文件的好工具,我会这样做:
答案 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。
答案 6 :(得分:1)
由于我从@BHF和@Daniel R的答案中获得的洞察力,我设法找到了一个合理可扩展的解决方案。
步骤1:将每个文件中的所有变量保存为单个结构
这使用Save workspace to struct - File Exchange submission。
假设您要比较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步:比较结构
这使用Compare Structures - File Exchange submission
鉴于您想要比较myStruct1
和myStruct2
,您只需致电:
[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文件可能并不太难。但是,特别是如果有一些大矩阵,我认为这可能会导致输出问题。