MATLAB Answers

0

How to read data after a specific word from txt file?

Asked by Xinying Ding on 11 Dec 2017
Latest activity Commented on by Joel Miller on 6 Dec 2019 at 14:14
I just start learning matlab. Now I want to read data from a txt file. The txt looks like this
EvtTime 12:11:33.034.438
Raw 0.00 m65S2c6 0.85 S1 22.43 S2 22.09 S3 -72.46
TTime 41:00:00.000.000 m65S2c7 0.02 S1 22.78 S2 23.35 S3 -44.46
TEHi 0.00 m65S2c11 -0.01 S1 22.66 S2 23.18 S4T03 22.15
TotalTm 160.38 S1T01 20.05 S1T11 23.55 S5T12 -11.18 S6BV08 42.26
LiveTm 114.63 S1T02 20.73 S1T10 20.33 S5T10 -15.52 S6BV05 42.13
EvtTime 12:15:23.225.518 65S2c7 0.01 S1-5C24 111.06 S2 23.41 S3 24.21
TotalTm 173.38 S1T01 21.95 S2T10 22.67 S3T19 -60.22 S4BV04 35.83
LiveTm 154.32 S1T02 21.70 S2T11 21.68 S3T20 -54.67 S4BV05 35.92
I need the value of 'EvtTime', 'TotalTm' and 'LiveTm', and the value is the number next to the words. The values should be read in vector. It will be like TotalTm = [160.38 170.38], and the LiveTm = [114.63 154.32]. The EvtTime will be read as time to plot. My code doesn't work well. Here is my code:
fid = fopen('data.txt','r');
while ~feof(fid)
st = fgetl(fid);
if ~isempty(findstr(st,'TotalTm'))
ftell(fid);
fseek(fid,-9,0);
F = cell2mat(textscan(fid,'%5d'))
end
st = fgetl(fid);
if ~isempty(findstr(st,'LiveTM'))
ftell(fid)
g = cell2mat(textscan(fid,'%5d'))
end
end
The value it read is not correct.And I don't know how two make the 'EvtTime' as a vector. Could you please help me to solve the problem ? Many thanks in advance.
Have a gread day
Ashley

  0 Comments

Sign in to comment.

3 Answers

Answer by Joel Miller on 11 Dec 2017

Hi, I think the code below will do what you want. It uses textscan on the line you have read instead of the entire text file; it creates column vectors for TotalTm and LiveTM and a column vector of strings for EvtTime. Using 'elseif' allows you to check each line for the three strings you are searching for.
F = [];
g = [];
h = [];
fid = fopen('testtext.txt','r');
while ~feof(fid)
st = fgetl(fid);
if ~isempty(strfind(st,'TotalTm'))
stread = textscan(st,'%s %f');
F = [F; stread{2}(1)];
elseif ~isempty(strfind(st,'LiveTm'))
stread = textscan(st,'%s %f');
g = [g; stread{2}(1)];
elseif ~isempty(strfind(st,'EvtTime'))
stread = textscan(st,'%s %s');
h = [h; stread{2}{1}];
end
end
fclose(fid);
You can convert the EvtTime strings into whatever format is convenient for plotting.

  1 Comment

Thanks Joel. Your contribution really works for me. However, I am running the script over multiple files using a loop. i find it difficult to collect each output as a vector. eg. F should be 10 values if i run the script over 10 files. the same goes for g and h
Any help will be appreciated
Thanks

Sign in to comment.


Answer by Joel Miller on 4 Dec 2019 at 21:51

Auwal, if I have a series of files in a directory, e.g. data1.txt, data2.txt, data3.txt, etc., I can use the directory command to get a structure with the file names, then loop the code above to put the results from all the files into vectors F, g, and h. Is this what you are looking to do?
F = [];
g = [];
h = [];
datafiles = dir('data*.txt');
for k = 1:length(datafiles)
fid = fopen(datafiles(k).name,'r');
while ~feof(fid)
st = fgetl(fid);
if ~isempty(strfind(st,'TotalTm'))
stread = textscan(st,'%s %f');
F = [F; stread{2}(1)];
elseif ~isempty(strfind(st,'LiveTm'))
stread = textscan(st,'%s %f');
g = [g; stread{2}(1)];
elseif ~isempty(strfind(st,'EvtTime'))
stread = textscan(st,'%s %s');
h = [h; stread{2}{1}];
end
end
fclose(fid);
end

  2 Comments

Thanks Joel, it works fine.
One more thing please. What if I want to extract three values thant are next to the word, all the values are seperated by commas.
Using the this solution I only get the first value.
thnks
Auwal, Akira's solution is preferable if your version of Matlab supports it. If you have an older version of Matlab, you can read additional numbers with a single call to textscan:
stread = textscan(st,'%s %f %f %f');
F = [F; stread{2}(1), stread{3}(1), stread{4}(1)];

Sign in to comment.


Answer by Akira Agata
on 4 Dec 2019 at 23:24

If your MATLAB is R2019a or later, you can use readcell function.
Also, by using indexing technique, you can do your task faster, like:
fileList = dir('data*.txt');
EvtTime = [];
TotalTm = [];
LiveTm = [];
for kk = 1:numel(fileList)
C = readcell(fileList(kk).name,'Delimiter','\r\n');
idx = startsWith(C,'EvtTime');
EvtTime = [EvtTime; regexp(C(idx),'[\d|:|.]+','match','once')];
idx = startsWith(C,'TotalTm');
TotalTm = [TotalTm; regexp(C(idx),'[\d|.]+','match','once')];
idx = startsWith(C,'LiveTm');
LiveTm = [LiveTm; regexp(C(idx),'[\d|.]+','match','once')];
end
TotalTm = str2double(TotalTm);
LiveTm = str2double(LiveTm);

  1 Comment

Thanks for your solution, Akira
Regards

Sign in to comment.