Подтвердить что ты не робот

Найти все различия между файлами .mat

Я ищу способ перечислить различия между двумя файлами .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


Поэтому мой вопрос:

Как показать все различия между двумя файлами mat с кем-то без Matlab


Вот ответы, которые я лично считаю наиболее подходящими для разных ситуаций:

4b9b3361

Ответ 1

Простой общий ответ без отображения различий значений

В связи с пониманием, которое я получил от ответов @BHF, @Daniel R и @Dennis Jaheruddin, мне удалось найти простое масштабируемое решение:

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

Обратите внимание, что он работает для .mat, содержащего произвольное число переменных.

Здесь используется Сравнить структуры - отправка файла.

Ответ 2

Найти все различия между матовыми файлами без MATLAB?

Вы можете найти различия между HDF5 на основе . mat files с HDF5 Tools.

Пример

Позвольте мне сократить ваш пример MATLAB и предположить, что вы создаете два файла мата с помощью

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 есть несколько команд и опций, которые могут помочь решить вашу реальную проблему.

Бинарные дистрибутивы доступны для Linux и Windows из Группа HDF. Для OS X вы можете установить их через MacPorts. При необходимости есть также графический интерфейс: HDFView.

Ответ 3

Если у вас есть 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')

как показано на этом скриншоте

enter image description here

Обратите внимание, что по умолчанию он ограничивает количество элементов в массивах до 1000, и вы можете увеличить его до 10000. Массивы, превышающие этот предел, будут сохранены в отдельном мат файле.

ОБНОВЛЕНИЕ: Из R2014a в MATLAB добавлена ​​новая функция, аналогичная Simulink.saveVars. см. matlab.io.saveVariablesToScript

Ответ 4

Это только часть ответа, но, возможно, это помогает.

Вы можете использовать gencode, функцию Matlab, которая генерирует код Matlab из переменной, так что запуск кода воспроизводит переменную. Вы делаете это для всех переменных в каждом мат файле (требуется некоторое программирование, но должно выполняться) и помещать результаты в разные .m файлы.

Затем вы можете использовать стандартный инструмент сравнения текста (возможно, даже visdiff) для сравнения .m файлов.

Ответ 5

Есть несколько хороших инструментов для сравнения XML файлов, это я бы сделал следующим образом:

  • Загрузить struct2xml.m
  • Загрузите оба matfiles
  • Экспорт каждого с помощью struct2xml
  • сравнить, используя XMLSpy или аналогичный

Ответ 6

Ответ для небольших файлов, отображающий все отличия значений

Основываясь на предположении @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

Хотя это может сработать, я не чувствую, что это лучший способ пойти.

Ответ 7

Общий ответ, без отображения различий значений

Благодаря пониманию, которое я получил от ответов @BHF и @Daniel R, мне удалось найти достаточно масштабируемое решение.

Шаг 1. Сохраните все переменные из каждого файла как одну структуру

Это использует Сохранить рабочее пространство для публикации структуры - Файл Exchange.

Вот шаги, которые следует предпринять, если вы хотите сравнить 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. Сравните структуры

В этом случае Сравнить структуры - представление файла Exchange

Учитывая, что вы хотите сравнить 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, если желательны отображения разности значений. Однако, особенно если есть некоторые большие матрицы, я полагаю, это может привести к проблемному выходу.