Возможно, это один из способов сделать это за один проход, но для меня эти проблемы проще сортировать с использованием подхода с 2-мя проходами.
- Передача 1: Прочитайте все столбцы с постоянным форматом в соответствии с их типом (строка, целое число и т. Д.) И прочитайте не постоянную часть в отдельном столбце, который будет обрабатываться во втором проходе.
- Пасс 2: Обработайте свою нерегулярную колонну в соответствии со своими особенностями.
В случае с данными выборки, это выглядит следующим образом:
%% // read file
fid = fopen('Test.txt','r') ;
M = textscan(fid , 'term%d %s %*c %[^]] %*[^\n]' ) ;
fclose(fid) ;
%% // dispatch data into variables
name = M{1,1} ;
time = M{1,2} ;
data = cellfun(@(s) textscan(s,'%f',Inf,'Delimiter',',') , M{1,3}) ;
Что случилось:
Первая textscan
инструкция читает полный файл. В спецификатора формата:
term%d
читать целое число после буквального выражения 'term'
.
%s
читать строка, представляющая дату.
%*c
игнорировать один знак (для игнорирования персонажа '['
).
%[^]]
читать все (как строка), пока не найдет символ ']'
.
%*[^\n]
игнорировать все до следующей строки новой строки ('\n'
). (Чтобы не захватить последнюю ']'
.
После этого, первые 2 столбца легко посланы в их собственных переменный. 3-й столбце массива результата ячейки M
содержит строки различной длины, содержащие различное число числа с плавающей точкой ,Мы используем cellfun
в сочетании с другим textscan
читать числа в каждой ячейке и возвращают массив ячеек, содержащий double
:
Бонус: Если вы хотите, чтобы ваше время, чтобы быть числовым значение, а (вместо строки), используйте следующее расширение кода:
%% // read file
fid = fopen('Test.txt','r') ;
M = textscan(fid , 'term%d %f-%f-%f-%f_%f_%f_%f %*c %[^]] %*[^\n]' ) ;
fclose(fid) ;
%% // dispatch data
name = M{1,1} ;
time_vec = cell2mat(M(1,2:7)) ;
time_ms = M{1,8} ./ (24*3600*1000) ; %// take care of the millisecond separatly as they are not handled by "datenum"
time = datenum(time_vec) + time_ms ;
data = cellfun(@(s) textscan(s,'%f',Inf,'Delimiter',',') , M{1,end}) ;
Это даст вам массив time
с временным серийным Matlab число (часто проще в использовании, чем строки). Для того, чтобы показать вам серийный номер по-прежнему представляют собой правильное время:
>> datestr(time,'yyyy-mm-dd HH:MM:SS.FFF')
ans =
2015-07-31 15:58:25.612
2015-07-31 15:58:25.620
2015-07-31 15:58:25.625
Так полезно для меня! Большое спасибо за ваш очень подробный ответ! – Hongwei