Reputation: 127
Is it possible to read a matrix under a specified headline from a text file? I have a text file like this:
Header A (2x3):
3 6 7
5 8 8
Header B (4x4):
23 65 2 6
4 6 7 8
33 7 8 9
so what I want to accomplish is to take the header names as an argument and grab the matrix under it. Is it possible to do in Matlab?
Thanks in advance!!
Upvotes: 2
Views: 279
Reputation: 1475
In addition, try to use this code:
infilename = '1.txt'; % name of your file
m = memmapfile(infilename); % load file to memory (and after close it)
instrings = strsplit(char(m.Data.'),'\n','CollapseDelimiters',true).';
checkstr = 'Header B';
% find all string (their indices) starting with checkstr
ind = find(strncmpi(instrings,checkstr,length(checkstr)));
data = [];
if isempty(ind)
fprintf('\n No strings with %s',checkstr)
else
% first string with string checkstr
n = ind(1)+1;
N = length(instrings);
while n<=N % find all numerical data after string with `checkstr`
convert = str2num(instrings{n});
if isempty(convert), break, end % find non-numerical data
data(end+1,1:length(convert)) = convert; % it because you can have various number of columns
n = n+1;
end
end
data % display load data
output
23 65 2 6 7
4 6 7 8 0
33 7 8 9 0
for the file 1.txt
:
Header A (2x3):
3 6 7
5 8 8
Header B (4x4):
23 65 2 6 7
4 6 7 8
33 7 8 9
Upvotes: 3
Reputation: 5429
The following would work, but might not be all that fast if you are dealing with a lot of data:
function [ matrixOut ] = readLineBasedOnHeader( headerString, FileName )
%readLineBasedOnHeader: Scan through a text file, and return matrix below
% a row which starts with the string `headerString`
% Read each row into cell array:
cellStrings = dataread('file', FileName, '%s', 'delimiter', '\n'); %#ok<DDTRD>
% Find the row matching headerString
headerIndex = ismember(cellStrings, headerString);
if sum(headerIndex) == 1
% We've found 1 match; return the matrix
% find how many rows have numberic
rowIdx = find(headerIndex)+1;
matrixOut = str2num(cellStrings{rowIdx}); %#ok<ST2NM>
stillAnumber = ~isempty(matrixOut);
if ~stillAnumber
error('row beneath header found not numeric');
end
while stillAnumber && rowIdx < length(cellStrings)
rowIdx = rowIdx+1;
nextRow = str2num(cellStrings{rowIdx}); %#ok<ST2NM>
stillAnumber = ~isempty(nextRow);
matrixOut = [matrixOut; nextRow]; %#ok<AGROW>
end
elseif sum(headerIndex) > 1
% More than 1 match; throw an error
error('More than 1 copy of header string found');
else % Less than 1 match; throw an error
error('Header string not found');
end
end
Assuming you have a file text_file.txt
with the content you have given above, then running:
readLineBasedOnHeader('Header A (2x3):', 'text_file.txt')
should return:
ans =
3 6 7
5 8 8
And running:
readLineBasedOnHeader('Header B (4x4):', 'text_file.txt')
Should return:
ans =
23 65 2 6
4 6 7 8
33 7 8 9
Note that this requires you input the full header line (i.e. an exact match for the row); but I'm sure you could have a play with this to get it to match just the Header A
bit.
Upvotes: 2