Clear Filters
Clear Filters

How can I change multiple lines in a text file?

3 views (last 30 days)
I have pasted a portion of a text file which I would like to edit, an example of what the modified file should look like and also my current output. For each material in the a text file I need to change a value, 2.5e8, to a random variable and I would like to generate many verions of the file with different random variables. The code I am using is as below.
clear all
clc
for n=1:1:20
fin = fopen('Ap1_Tr_Disp_Int.inp')
fout = fopen([num2str(n), '.inp'], 'w')
while ~feof(fin)
s = fgetl(fin)
r = 2.5e8 + 2.5e7*randn(1,1)
s = strrep(s, ' 2.5e8, 0', [' ', num2str(r), ', 0'])
s = strrep(s, ' 2.5e8, 0.005', [' ', num2str(r), ', 0.005'])
fprintf(fout,'%s\n',s)
end
end
fclose(fin)
fclose(fout)
The problem with the code is that it changes both instances of 2.5e8 (see below) to different random variables. I have spent ages trying to figure this out, however I am new to Matlab. Any help would be greatly appreciated!
Original Text File
*Material, name=Steel_1
*Elastic
2e+11, 0.3
*Plastic
2.5e8, 0 (I want to change 2.5e8 to a random variable)
2.5e8, 0.005 (for each material, new variables should be the same)
1e3, 0.0050001
**
*Material, name=Steel_2
*Elastic
2e+11, 0.3
*Plastic
2.5e8, 0
2.5e8, 0.005
1e3, 0.0050001
.....etc
Example of desired output
*Material, name=Steel_1
*Elastic
2e+11, 0.3
*Plastic
2.7e8, 0
2.7e8, 0.005
1e3, 0.0050001
**
*Material, name=Steel_2
*Elastic
2e+11, 0.3
*Plastic
2.35e8, 0
2.35e8, 0.005
1e3 , 0.0050001
.....etc
Example of my current output
*Material, name=Steel_1
*Elastic
2e+11, 0.3
*Plastic
2.3e8, 0
2.9e8, 0.005 (2.3e8 and 2.9e8 should be the same)
1e3, 0.0050001
**
*Material, name=Steel_2
*Elastic
2e+11, 0.3
*Plastic
2.7e8, 0
2.4e8, 0.005 (2.7e8 and 2.4e8 should be the same)
1e3 , 0.0050001
.....etc

Accepted Answer

Nishitha Ayyalapu
Nishitha Ayyalapu on 17 Oct 2013
Edited: Nishitha Ayyalapu on 17 Oct 2013
Here is the working code. Small tweaks to your existing code solved the problem.
1.) Generate a random only for new type of material.
2.) Do the String replace only once whenever the line has target string "2.5e08".
doc strfind
Below is the Modified Code:
clear all
clc
for n=1:1:20
fin = fopen('Ap1_Tr_Disp_Int.inp') ;
fout = fopen([num2str(n), '.inp'], 'w');
occur = 1; %counting ooccurrences of the string '2.5e8'
while ~feof(fin)
%generates new random number only for odd num of occurrences
if (mod(occur,2))
r = 2.5e8 + 2.5e7*randn(1,1);
end
s = fgets(fin);
if (~isempty(strfind(s,' 2.5e8')))
reps = num2str(r(1));
s = strrep(s, ' 2.5e8', [' ',reps])
occur = occur + 1; %if the target string occurs increment
end
fprintf(fout,'%s',s)
end
end
fclose(fin);
fclose(fout);
Hope this helps !!

More Answers (1)

Cedric
Cedric on 18 Oct 2013
Edited: Cedric on 18 Oct 2013
Just for fun, here is a one-liner for reading/replacing (that I write on 3 lines for sake of clarity):
repl = regexprep( fileread( 'Ap1_Tr_Disp_Int.inp' ), ...
'(Plastic\s+)2.5e8(.+?)2.5e8', ...
'${sprintf([$1,''%.1e'',$2,''%.1e''],2.5e8+2.5e7*repmat(randn(1),1,2))}' ) ;
As you are always dealing with the same source file, the whole code would reduce to something like ..
content = fileread( 'Ap1_Tr_Disp_Int.inp' ) ;
newContent = @() regexprep( content, ...
'(Plastic\s+)2.5e8(.+?)2.5e8', ...
'${sprintf([$1,''%.1e'',$2,''%.1e''],2.5e8+2.5e7*repmat(randn(1),1,2))}' ) ;
for k = 1 : 20
fid = fopen( sprintf('%02d.inp', k), 'w' ) ;
fwrite( fid, newContent() ) ;
fclose( fid ) ;
end
  2 Comments
Colin
Colin on 20 Oct 2013
Edited: Colin on 20 Oct 2013
Thanks for the suggestion. It appears to be much more efficient that any other solutions I have tried.
Cedric
Cedric on 20 Oct 2013
You're welcome. The drawback is that it involves a call to REGEXPPREP that nobody will ever want to debug if there is a problem ;-)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!