DanielleC
DanielleC

Reputation: 127

Matlab: How to read and extract matrix by specifying header name?

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

Answers (2)

Alexander Korovin
Alexander Korovin

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

kabdulla
kabdulla

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

Related Questions