MATLAB Answers

0

how to change multiple items in a text file?

Asked by Idin Pushkin on 3 May 2019
Latest activity Commented on by Stephen Cobeldick on 10 May 2019
hello
i have a text file with name of bp. u see many 'TSTEP' in this file. there are other written text just below them like: '1*100'. now i want to find these 'TSTEP's and make changes on the text below them (just changing the number before the asterisk). for example '1*100' is going to be '2.5*100' or any other number can be replaced. i use this code when i have one 'TSTEP' in file. ut it doesnt work for the cases when there are more than one of it. the number of TSTEPs may differ from file to file. is it possible to do that?
thanks in advance
clc;
fid=fopen('bp.txt','r');
c=textscan(fid,'%s','delimiter','\n','Whitespace','','CommentStyle','1','CollectOutput',0);
fclose(fid);
c=string(c{:})
iz=find(contains(c,"TSTEP"));
d1=['2.5','*',extractAfter(c{iz+1},'*')];
d2=replace(c,c{iz+1},d1);
fid = fopen('bp.txt','w');
for j= 1:length(d2)
fprintf(fid, '%s\n', char(d2{j}));
end
fclose(fid);

  0 Comments

Sign in to comment.

Tags

No tags entered yet.

2 Answers

Answer by Stephen Cobeldick on 3 May 2019
Edited by Stephen Cobeldick on 7 May 2019
 Accepted Answer

EDIT: much faster:
rpl = '2.5'; % the new value (you can generate this using NUM2STR).
str = fileread('bp.txt');
str = strtrim(regexp(str,'\n','split'));
idx = 1+find(strcmpi(str,'TSTEP'));
str(idx) = regexprep(str(idx),'^[^*]+',rpl);
fid = fopen('pb_new.txt','wt');
fprintf(fid,'%s\n',str{:});
fclose(fid);
ORIGINAL (SLOW): With a simple regular expression and regexprep:
rpl = '2.5'; % the new value (you can generate this using NUM2STR).
rgx = '(?<=\s+TSTEP\s+)\d+(?=\*100)'; % regular expression.
% Read old file and replace data:
old = fileread('bp.txt');
new = regexprep(old,rgx,rpl);
% Save the new file:
fid = fopen('bp_new.txt','wb');
fprintf(fid,'%s',new);
fclose(fid)
The input and output files are attached.

  23 Comments

@Idin Pushkin: I am very surprised that your code works without error:
str = fileread('bp.txt','r');
% ^^^^ What is this supposed to do?
I cannot find any indication in the documentation that fileread accepts two input arguments.
That loop serves absolutely no purpose: you simply generate and discard str2 multiple times, but keep only the final str2 value. You can also get rid of the cell2mat here:
str2double(cell2mat(str1(i)))
str2double(str1(i)) % simpler and more efficient
Most likely that entire calculation can be done without a loop anyway:
vec = str2double(str1) .* str2double(rpl)
"there may be different numbers before '*' ..."
Previously you indicated that you wanted to use one new value to replace all TSTEP old values: doing so is easy using the code that I have given you. However if you want each TSTEP old value to be replaced with its own special value then using a loop is probably simplest (with indexing into the vectors idx and vec).
str = fileread('bp.txt');
% ^^^^ What is this supposed to do?
it was spelling mistake about the above code. about the loop u said i use this code and doesnt work again
for i=1:length(vec)
str(idx) = regexprep(str(idx),'^[^*]+',num2str(vec(i)));
fid = fopen(newStr1,'wb');
fprintf(fid,'%s\n',str{:});
fclose(fid);
end
I wrote "with indexing into the vectors idx and vec..."
You are using i with vec (which is good) and ignored idx (which is not good).
You can see that the elements of idx correspond to the elements of vec... therefore if you use indexing into vec then you will also need exactly the same indexing into idx (just as I wrote in my comment).
Note the putting the file writing code inside that loop just overwrites the file contents on each iteration. In the end, only the last iteration will remain, so there is no point in this being isnide the loop (apart from slowing down your code and heating up your room).

Sign in to comment.


Answer by KSSV
on 3 May 2019
Edited by KSSV
on 3 May 2019

fid = fopen('data.txt','r') ;
S = textscan(fid,'%s','delimiter','\n') ;
fclose(fid) ;
S = S{1} ;
% Get indices Tsteps
idx = find(contains(S,'TSTEP'))+1 ;
% Replace the number
S1 = S ;
S1(idx) = {'2.5*100'} ;
% Write to file
fid = fopen('test.txt','w') ;
fprintf(fid,'%s\n',S1{:});
fclose(fid);
NOTE: If contains is not available, you can use strcmp, ismember.

  8 Comments

KSSV
on 3 May 2019
d=['2.5*',extractAfter(S(idx),'*')]
it doesnt make a difference. makes 1*2 cell arrays.
Your idx is non-scalar because you have multiple matches in the file. extractAfter needs to return multiple values.

Sign in to comment.