You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to get the highlighted parts from the text file to another separate text file?
4 views (last 30 days)
Show older comments
Subaharan Rajenthirakumar
on 11 May 2022
Commented: Subaharan Rajenthirakumar
on 13 May 2022

13 Comments
Mathieu NOE
on 11 May 2022
hello
it would help if you would share the file as well
my first idea would be to use readlines , then use some text like "node foot" to get the 3 index of the corresponding lines
what we look for is data in the lines that are +3 rows after "node foot" lines
dpb
on 11 May 2022
Exactly what @Mathieu NOE says...I just posted an Answer to essentially the same Q? on a different file here <Reading-text-file-and-searching-for-specific-lines#answer_960695> a couple of days ago. Your case mimics finding the sections and reading the number of lines per section there without the need for the other array, but shouldn't take more than a few simple edits to work almost as is.
Subaharan Rajenthirakumar
on 11 May 2022
I have attached the file here. Thank you in advance for helping me
dpb
on 11 May 2022
Show us what you've done with the sample code and where you ran into a problem...
Subaharan Rajenthirakumar
on 11 May 2022
clc;
clear;
% get the input file by giving the name of the input file
inputFilevector = ["Sandwich_Panel.inp"];
for filecounter = 1:1
filename = inputFilevector(1,filecounter); % initiation of Abaqus into Matlab
%Read text into cell A
fid = fopen(filename,'r'); % take individual file and open in Matlab
i=1;
tline = fgetl(fid);
A{i} = tline; % add line by line to this string vector A
while ischar(tline) % check for the character and go until empty
i = i+1;
tline = fgetl(fid);
A{i} = tline;
end
fclose(fid);
%% Locate the material properties - we are interested in changing those
data1 = textread(filename, '%s', 'delimiter', '\n'); % Edit input file to the path of your text file-> getting the particular file to this vector
% Find the row(s) that holds the string we are looking for
rowid_1 = find(~cellfun('isempty',strfind(data1,'*Material, name=Insul_mat_1')));
rowid_2 = find(~cellfun('isempty',strfind(data1,'*Material, name=Insul_mat_2')));
% simply run a for loop to check with various values for your
% parametric studies
%% change the Material Properties
%material conducitivities for FiberGlass, PlasterBoard, EPS and Plywood
mat = ["PB","EPS","SB"];
mat_conductivity = [0.16,0.035,0.093];
mat_list = [];
%k = 0;
for a = 1:length(mat_conductivity)
%k = k + 1;
for j = 1:length(mat_conductivity)
Material = mat(a)+'_'+mat(j);
mat_list = [mat_list; Material];
Material = convertStringsToChars(Material);
% substitute the new values in the appropriate locations
A{rowid_1+2} = sprintf('%d',mat_conductivity(a));
A{rowid_2+2} = sprintf('%d',mat_conductivity(j));
%% Write cell A into txt
token = convertStringsToChars(strtok(filename,'.')); % Return the first part of the string (file name) using the '.' character as a delimiter
% use that specific token to create the file names
inpfilename = ['inp_',token,'_',Material,'.inp'];
jobname = ['job',lower(token)]; % remember this name because it has to be used in an upcoming line
% writing in the input file from modified A
fid = fopen(inpfilename, 'w');
for i = 1:numel(A)
if A{i+1} == -1 % go until empty
fprintf(fid,'%s', A{i});
break
else
fprintf(fid,'%s\n', A{i});
end
end
fclose(fid);
%% Run Abaqus
runAbaqus = ['abaqus job=',Material,' input=',inpfilename,' interactive'];
dos(runAbaqus);
end
end
end
%% Extract temperatures at three nodes on each internal surfaces
mat_list_new = mat_list+".dat"; %list of created data file in the directory
% get the output data file for results extraction
datFilevector = mat_list_new;
for filecounter = 1:length(mat_list_new)
filename = datFilevector(filecounter,1);
% Read text into cell AA
datfid = fopen(filename,'r');
i = 1;
tline = fgetl(datfid);
AA{i} = tline; % add line by line to this string vector A
while ischar(tline) % check for the character and go until empty
i = i+1;
tline = fgetl(datfid);
AA{i} = tline;
end
% locate the analysis completion line in dat file
data1 = textread(filename,'%s', 'delimiter', '\n');
endrowid = find(~cellfun('isempty',strfind(data1,'THE ANALYSIS HAS BEEN COMPLETED')));
% Locate the result lines by finding out the size of node outputs
nodeOutputLen = 44;
nodeOutputstartRow = endrowid - nodeOutputLen;
% write the extracted results to a separate file
writefilename = mat_list(filecounter)+'.txt';
testfid = fopen(fullfile('D:\Sem 8\Computational Mechanics\25mm_50mm', writefilename),'w+'); % open that file
for i = nodeOutputstartRow: endrowid-2
if AA{i+1} == -1 % go until empty
fprintf(testfid,'%s', AA{i});
break
else
fprintf(testfid, '%s\n', AA{i});
end
end
fclose(testfid);
fclose(datfid);
end
This is the code that I scripted to extract the text file that I attached earlier. I will get many such text files and I need those highlighted values from each text file as a matrix or a table or whatever format for postprocessing (sorting actually).
I don't actually have an idea to extract three values from each text files. I need a bit of a help in that. Thank you in advance.
Subaharan Rajenthirakumar
on 11 May 2022
If you want to run this code, then you may need the input file which I couldn't attach here because the file format is not supported it says.
dpb
on 11 May 2022
Did you even look at the code in the Answer I linked to above?
It would let you find the values you're looking for in about five lines of code or less...I'll duplicate that code here; start with this as the model of how to do it...
D=readlines('Full_TableX.txt'); % read as string array
ixP1=find(contains(D,'Pipe')); % find the pipe sections
nP=str2double(extractAfter(D(ixP1+2),',,')); % read the number lines
for i=1:numel(ixP1) % process each section in turn
Pipe{i}=str2double(split(strtrim(D(ixP1(1)+4:ixP1(1)+4+nP(1)-1))));
end
This person had a file where the magic text to find was either 'Pipe' or 'Cable' and to pull nP lines of data in the file abvout four lines past that point. The value nP was the number of lines which occurred exactly 2 lines past the magic text.
In your case, the "magic string" is "NODE FOOT" and the numbers you're after are three lines after those lines -- wonn't take much at all to modify the above to do that and you'll have learned something (mostly) on your own instead of just having something handed to you...
dpb
on 11 May 2022
D=readlines('SB_PB.txt');
ix=find(contains(D,'NODE FOOT'));
NodeData=cell2mat(arrayfun(@(i)str2double(split(strtrim(D(i+3)))).',ix,'UniformOutput',0));
returns
>> NodeData =
3159 36.019
1558 28.761
6466 20.324
>>
for the specific sample file.
The code you attached doesn't appear to have much relation to the initial Q? and file with the highlighted data???
Subaharan Rajenthirakumar
on 12 May 2022
@dpb Thank you and I actually missed your comment earlier. And the text file that I shared earlier will be generated from the code that I attached later. Many such text files will be generated with different names (FG_PB, SP_PB, EPS_PB etc).
I tried several methods to retrive those three lines from each text file with the name of the text file and fedup. Then I came to the forum for a help.
And, how exactly you or others are able to come up with codes like these
NodeData=cell2mat(arrayfun(@(i)str2double(split(strtrim(D(i+3)))).',ix,'UniformOutput',0));
I don't have a coding background and have been learning for little over two months now and your answer may help. The books I referred so far are either for high school students or for CS or mathematicians.
dpb
on 12 May 2022
"...And, how exactly you or others are able to come up with codes like these..."
30+ years using MATLAB builds an experience level beginners won't have -- particularly if do not have any programming in background, so don't beat yourself up for not coming up with it! <VGB>
However, a few guidelines -- first is one of simply finding the appropriate functions in the huge space of all the MATLAB functions -- in this case knowing that readlines exists basically requires either just already knowing about it or looking through the doc at all the file i/o functions and then reecognizing this is one that could really help me for this problem amongst all the available choices.
That's also tempered by experience and an idea of how to go about solving the problem -- in these kinds of cases, I already know that in general one can use MATLAB vector operations effectively so I'm looking for array operations, not line-by-line parsing of a file -- sometimes, that is what one must do, so that's also a very useful tool, but not needed here.
From that it's then recognizing that there is a specific pattern to search for and the desired data is always a fixed position relative to those--and also knowing that MATLAB works best when can use vectorized operations -- so that can get the index vector in one step to identify each wanted section in the file.
Then, the processing -- to write this using arrayfun() is a fairly advanced level of experience with MATLAB -- you will get to that point if you continue to use MATLAB and are adventureous enough to explore more than the merest of basics. It is simply a higher-level construct for a for...end loop which construct is needed to then process each of the lines we've identified above as being the anchors for the data we're trying to extract.
At that point, it's a choice -- write short MATLAB code (something there are contests about occasionally, "MATLAB golf" :) ) or write out the pieces separately. Beginners may well start writing the pieces explicitly; with experience one recognizes that one function can operate on the output of another without the need for creating an intermediary temporary variable to hold the results of the first to pass to the second -- that's all that's going on here.
Starting from the inside out; we identified that the row of interest is three lines past the anchor line -- and the index array ix is the argument array arrayfun uses to pass each entry in that array to the anonymous function in turn -- the "(i)" argument variable.
So
D(i+3) % the target line, "i" is each value of ix, in turn
strtrim() % remove any spurious blanks from the line before/after the content
split() % turn the line into the two numeric pieces separately
str2double() % convert those two text strings to numbers
The result there will be a 2-vector of numbers; since the index vector being passed, ix is a column vector because we searched the 1D column string array D the two values returned will also be a column vector each iteration through. Hence, to put them together as they are in the file and for convenience in viewing, the trailing ".'" (the 'dot' transpose operator) converts the column vector to a row vector. So, each pass gives us the two numbers for each line of each section.
Since we're returning more than one result with each pass through the array ix, arrayfun() requires the output be a cell array -- that's what the 'UniformOutput',1 tells it; without it we would get an error message telling us there are multiple outputs and we've got to use a cell output.
The last part is then simply converting the cell array to the numeric underlying data type of the content of the cell and collecting those pieces together into an ordinary double array. That relies wholly on the fact that we know the data we are parsing is always going to be numeric and that there are always going to be two values -- if that wasn't the case, this step would fail.
It looks daunting, granted, and it is not what one would expect the neophyte to come up with; but it makes use of the features of MATLAB that make MATLAB such a help -- and to illustrate such and to try to guide "newbies" in the direction of better productivity with MATLAB is a major reason I participate here and post such pieces of code -- to teach as well as simply solve a specific problem. Plus, it's just kinda' fun when one can get such a result in such a short piece of code! :)
The above pattern is a general problem-solving tool for such cases -- it can be applied to any case in which there is a search and then a particular reference from that point almost verbatim for any number of cases; only the minor details of the specific search string and the offset and form of the data need be tweaked for specifics. Sometimes there may need to be an additional search within the section or more exotic searches may be needed, but the overall idea of bringing the data into memory and then operating over it is a key concept. One may eventually run into files that are too large to fit in memory and have to resort to other techniques, but this is probably the way to approach almost every such problem initially.
Subaharan Rajenthirakumar
on 12 May 2022
@dpb I really appreciate the effort and time you took to explain the thoughtprocess to solve the problem. Thank you very much. I have a very long way to go it seems.
dpb
on 12 May 2022
Glad to help...teaching is part of the job...
Actually, it just dawned on me that I didn't do the best job that could have on the above code -- one can do it entirely in a vectorized form without arrayfun at all that simplifies the code quite a bit. Even w/ 30 years, one can pick the wrong function for the job--if use split instead of strsplit on the string array, one can write
>> NodeData=str2double(split(strtrim(D(ix+3))))
NodeData =
3159 36.019
1558 28.761
6466 20.324
>>
and the whole solution is fully vectorized.
MORAL: Don't feel bad in missing a better tool/function; even experienced users can either by not being familiar with the whole lexicon or simply not thinking of the better choice. split was introduced in R2016b in conjunction with the new string class and had the advantage that it is vectorized whereas the venerable strplit for cellstr and char strings prior to the introduction of strings is not...being an old-timer sometimes is a hindrance; it's the old friends that one thinks of first automagically as I did here.
>> strsplit(strtrim(D(ix+3)))
Error using strsplit (line 80)
First input must be either a character vector or a string scalar.
>>
I knew this would happen; hence the use of arrayfun to pass each individually; just whiffed on remembering split at the time.
Accepted Answer
dpb
on 12 May 2022
Edited: dpb
on 12 May 2022
D=readlines('SB_PB.txt');
ix=find(contains(D,'NODE FOOT'));
NodeData=str2double(split(strtrim(D(i+3))));
to simplify the solution using arrayfun in earlier comments.
NB: Use of new(ish) split() function for strings in place of venerable non-vectorized strsplit requiring the looping construct.
>> NodeData=str2double(split(strtrim(D(ix+3))))
NodeData =
3159 36.019
1558 28.761
6466 20.324
>>
As opposed to the nonvectorized strsplit
>> strsplit(strtrim(D(ix+3)))
Error using strsplit (line 80)
First input must be either a character vector or a string scalar.
>>
which thus needs the looping construct.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)