Find a word in a file then pick the value next to it

3 views (last 30 days)
Good morning everyone,
I am trying to open a file, find a keyword and pick the value next to it. I tried using the command regexp but I don't have the good result.
Here is my file :
*SET,MAX_ANCRAGE_X_6881, 185.5679805275
*SET,MAX_ANCRAGE_X_6952, 332.0771666276
*SET,MAX_ANCRAGE_X_6968, 194.5047935943
*SET,MAX_ANCRAGE_X_7011, 321.4175275594
*SET,MAX_ANCRAGE_Y_6881, 412.8217963186
*SET,MAX_ANCRAGE_Y_6952, 202.2417053201
*SET,MAX_ANCRAGE_Y_6968, 580.6889503183
*SET,MAX_ANCRAGE_Y_7011, 165.7298365705
*SET,MAX_ANCRAGE_Z_6881, 3354.728736175
*SET,MAX_ANCRAGE_Z_6952, 4722.802350600
*SET,MAX_ANCRAGE_Z_6968, 3274.569376437
*SET,MAX_ANCRAGE_Z_7011, 3042.275382807
*SET,MAX_DEPLACEMENT, 0.1533135713205E-02
*SET,MAX_DISPLACEMENT, 0.1905912931085E-05
*SET,MAX_VM , 39323548.00000
*SET,MODULE_YOUNG, 210000000000.0
*SET,MODULE_YOUNG_RIGIDE, 0.2100000000000E+15
I would like to perform a loop as
for i=[6881 6952 6968]
find the value next to MAX_ANCRAGE_X_i and store it into a matrix (3*3)
then do the same with MAX_ANCRAGE_Y_i
then do the same with MAX_ANCRAGE_Z_i
end
My objective is to have
(Max_Ancrage_X_6881 Max_Ancrage_Y_6881 Max_Ancrage_Z_6881)
(Max_Ancrage_X_6952 Max_Ancrage_Y_6952 Max_Ancrage_Z_6952)
(Max_Ancrage_X_6968 Max_Ancrage_Y_6968 Max_Ancrage_Z_6968)
Thanks you really much for your help !
Thibaut
  4 Comments
Johannes Rebling
Johannes Rebling on 5 May 2020
So the final result should be:
(185.5679805275 412.8217963186 3354.728736175) etc?

Sign in to comment.

Accepted Answer

Johannes Rebling
Johannes Rebling on 5 May 2020
Edited: Johannes Rebling on 5 May 2020
One way would be regexp, another would be strfind, see doc strfind.
str = '*SET,MAX_ANCRAGE_X_6881, 185.5679805275';
i = 6881;
searchStr = sprintf('MAX_ANCRAGE_X_%04i',i);
strStartIdx = strfind(str,searchStr);
numberStartIdx = strStartIdx + numel(searchStr) + 3
numberStr = str(numberStartIdx:end);
value = str2double(numberStr)

More Answers (3)

dpb
dpb on 5 May 2020
buf=importdata('thibaut.dat'); % get the data in; how is your choice...importdata leaves .text, .data
ix=contains(buf.textdata(:,2),'ANCRAGE'); % splits at comma delimiter so is in second column
nodes=str2double(extractAfter(text,max(strfind(text(1),'_')))); % extract the node numbers for info
iWant=[6881 6952 6968]; % the desired subset
xyz=zeros(numel(iWant),3); % preallocate the output array
for i=1:numel(iWant)
xyz(i,:)=buf.data(ismember(nodes,iWant(i))).';
end
Results in
>> format bank
>> xyz
xyz =
185.57 412.82 3354.73
332.08 202.24 4722.80
194.50 580.69 3274.57
>>
Have the nodes array to go with to identify which is which...using lookup in an array is much simpler than coding explicit variable names containing metadata--that way "there be dragons!"

Stephen23
Stephen23 on 5 May 2020
>> str = fileread('test.txt');
>> rgx = 'MAX_ANCRAGE_[XYZ]_(?:6881|6952|6968),\s+(\d+\.?\d*)';
>> tkn = regexp(str,rgx,'tokens');
>> mat = reshape(str2double([tkn{:}]),[3,3])
mat =
185.57 412.82 3354.7
332.08 202.24 4722.8
194.5 580.69 3274.6

TADA
TADA on 5 May 2020
You've got the right idea. Regular expressions can be confusing at times I tested the regexp, the rest of the code is not tested but I trust you to make it work
data = fileread('whatever file name');
% this is the regexp pattern, we use
% sprintf to insert the x/y/z and
% number later.
% This is why the backslash is escaped
pattern = 'MAX_ANCRAGE_%s_%d,\\s*(\\d*\\.?\\d*)';
ids = [6881 6952 6968];
varNames = {'X', 'Y', 'Z'};
out = zeros(numel(ids), numel(varNames));
for i = 1:numel(ids)
for j = 1:numel(varNames)
tok = regexp(sprintf(pattern, varNames{j}, ids(i)), 'tokens');
val = tok{1};
out(i,j) = str2double(val{1});
end
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!