MATLAB Answers

0

Import and find a specific number from a text file

Asked by Adrian Ulza on 20 Jan 2017
Latest activity Edited by David J. Mack on 20 Jan 2017
hey, i am trying to take out a specific value from a text file.
Let say, i want to get the absolute maximum value (Max and Min) from UX column only. Since the NODE column and LC column will vary for each analysis output, hence i would like to avoid to scan it by line number.
Thank you for your help,
Adrian
________________________________________________
NODE DISPLACEMENT AND ROTATIONS DEFAULT PRINTOUT Unit System : kgf , cm
__________________________________________________
NODE LC UX UY UZ RX RY RZ
------ -------- ---- ----------- ----------- ----------- ----------- ----------- -----------
01 0.1g Max 0.410 0.000 0.012 0.0 0.0 0.0
Min -0.364 0.000 -0.011 -0.0 -0.0 0.0
0.2g Max 0.795 0.000 0.022 0.0 0.0 0.0
Min -0.683 0.000 -0.020 -0.0 -0.0 0.0
0.3g Max 1.137 0.000 0.031 0.0 0.0 0.0
Min -1.003 0.000 -0.028 -0.0 -0.0 0.0
...
...
98 0.1g Max 0.549 0.000 0.035 0.0 0.0 0.0
Min -0.493 0.000 -0.038 -0.0 -0.0 0.0
0.2g Max 1.047 0.000 0.061 0.0 0.0 0.0
Min -0.911 0.000 -0.068 -0.0 -0.0 0.0
0.3g Max 1.495 0.000 0.088 0.0 0.0 0.0
Min -1.328 0.000 -0.096 -0.0 -0.0 0.0
________________________________________________
BEAM ELEMENT FORCES & MOMENTS DEFAULT PRINTOUT Unit System : kgf , cm
________________________________________________
ELEM MAT SEC BC PT AXIAL SHEAR-y SHEAR-z TORSION MOMENT-y MOMENT-z

  4 Comments

Show 1 older comment
@Adrian Ulza: please edit your question and upload the file by clicking on the paperclip button.
hey, sorry. i've just attached the file.
You may be able to wangle it by reading the whole text file and using some clever regexes but to do the job properly you're going to have to write your own parser.
That text format is not really designed to be read by a computer. If the program you're using has an alternative output format (binary would be better) that is documented, I'd consider using that instead.

Sign in to comment.

1 Answer

Answer by David J. Mack on 20 Jan 2017
Edited by David J. Mack on 20 Jan 2017

Try use regexp:
file='c:\Users\David J. Mack\Desktop\test.txt';
numFormat1 = {'[ ]{1,7}(\-?\d+\.\d{3})'}; %e.g. %12.3f
numFormat2 = {'[ ]{1,9}(\-?\d+\.\d{1})'}; %e.g. %12.1f
% ---NODE----------------- ---LC----------------- ------------ ---UX/UY/UZ--------- ---RX/RY/RZ--------- ---EOL
C=regexp(fileread(file),['[ ]{0,6}([1-9]+\d{0,5})?[ ]{1,9}(\d+\.\d{1}g)? (Min|Max)' [numFormat1{[1 1 1]} numFormat2{[1 1 1]}] '\r\n'],'tokens');
C=vertcat(C{:});
absMax = max(abs(str2num(char(C(:,4))))); % Compute abs. max over min/max.
If the format of the file is fixed like that, absMax contains the abs. max. of min & max. The regex pattern simply defines the numbers with spaces.
As pointed out by Guillaume, this will fail if there are more tables with the same format in your file. Greetings, David
EDIT: Added suggestions by Guillaume
P.S.: If you want to do some processing on your data, modify the following hack>
tbl = C;
isEmpt = cellfun(@isempty,tbl(:,2));
tbl(isEmpt,2) = tbl(~isEmpt,2); % Assume every other row is empty
tbl(:,2) = strrep(tbl(:,2),'g','');
tbl = cell2table(tbl,'VariableNames',{'Node','LC','Type','UX','UY','UZ','RX','RY','RZ'});
tbl.Node = cumsum(~cellfun(@isempty,tbl.Node));
tbl.Type = categorical(tbl.Type);
for var = {'LC','UX','UY','UZ','RX','RY','RZ'}
tbl.(var{:}) = str2num(char(tbl.(var{:})));
end

  2 Comments

You're reading the file twice!
You're going to need a more complex pattern to match each number as at the moment it fails to match negative numbers.
Probably a better pattern for numbers:
[+-]\d+.\d+ %instead of [ 0-9]{x}
Also because of ([ \.0-9]{7})g the pattern will fail to match the Min lines.
This also assumes that the UX column always follow Min/Max and that no other table in the file has numbers after the Min/Max column. It appears to be the case as the other (non UX) tables have a letter in the column after the Min/Max column but you need to be sure that it's always the case.
This pattern may or may not work:
regexp(fileread(file), '(?<=Min|Max)\s+([+-]?\d+.\d+)', 'match')
My bad! That was just for the testing. Removed the first (unnecessary call). Also updated the numbers. Thanks for the hint (will use the \d+\.\d+ otherwise you would match any char between the numbers.
As I wrote, this will work only if the file is in the format as specified (where no other table has a similar format).

Sign in to comment.