How to change a specific part in a specific line in a text file?

Hi,
I have a txt file and I need to change specific numbers in specific lines,
line 131, a = 10
line 132, b = 30
is any way to change the above lines to:
a = 5
b = 60

2 Comments

I am facing problem in replacing decimal number to integer or new decimal number
for example old a =2.4 and new a= 200 or new a =5.6
I've tried
regexprep(contents, {'a = \f+'}, {sprintf('a = %g', newa)}); the digits after the point are not recognized
'\d+' to recognize only decimal digits
'\d+(\.\d*)?' to recognize decimal digits that might optionally be followed by a '.' that in turn might be followed by digits
If the number might be negative, start the pattern with '-?'
If the number might have floating point exponent then it starts to get ugly to write the expression.

Sign in to comment.

 Accepted Answer

contents = fileread('test.txt');
newa = 10;
newb = 123;
newcontents = regexprep(contents, {'^a\S*=\S*\d+', '^b\S*=\S*\d+'}, {sprintf('a = %d', newa), sprintf('b = %d', newb)});
fid = fopen('test_new.txt', 'wt');
fwrite(fid, newcontents);
fclose(fid);

4 Comments

using 'regexprep' is great, but I got the same original text without any change to lines a & b, besides the size and lines of the new text file is doubled because all lines now separated by blank line or row.
Add the 'lineanchors' option to the regexprep call.
Change 'wt' to 'w'
{'a = \d+', 'b = \d+'}
Many thanks Walter
100% working
Dear community,
I have many txt files that uses a tab delimiter. I have to change the content between the 17th and 18th tab delimiter of all my files. This is one the data inside the file:
_______
Data file generated on Tue Aug 30 12:40:29 2022
A B C D E F G H I J K L M N O P Q R S T U
1 2.00000 2.00000 0.00000 1.00000 28.00000 64.00000 88.00000 1.20000 275.00000 50.00000 30.00000 165.00000 850.00000 500.00000 0.00000 10.00000 10.00000 15.00000 0,0,0,0, 0,0,0,0, false
_______
So I have to change the value for the variable Q (in this case 10.0000) for a specific value. However, some of my files have a different pattern for numbers, instead of 10.00000 it is only 10, what makes the counting characters unfeasible. Furthermore, after some delimiters there are spaces. Then, I decided to count the tab delimeters, and change the content between the 17th and 18th delimiter to solve my problem, that I don't know if it will work. This is my code so far...
ThemeCopy
A = regexp(fileread(myfile), '\n', 'split'); %upload my file to a cell array
B = strfind(A{4}, sprintf('\t')); %takes the cell 4 in the array and finds where I have tab delimiters
C = B{4}(17)+1:B{4}(18)-1; %select the content between the 17th and 18th tab delimiters
Please, can somebody help me???

Sign in to comment.

More Answers (2)

Use
patchline('test.txt', 'a = 5', 132)
patchline('test.txt', 'b = 60', 133)
using my function
function patchline(filename, newstring, lineno)
%PATCHLINE
%
%Thorsten.Hansen@psychol.uni-giessen.de
fid1 = fopen(filename, 'r');
if fid1 == -1
error(['Cannot open file ' filename ' for reading.']);
end
tempfilename = 'temp1.txt';
fid2 = fopen(tempfilename, 'w');
if fid2 == -1
error(['Cannot open file ' filename ' for writing.']);
end
line = fgets(fid1);
i = 1;
while line ~= -1
if i == lineno
fprintf(fid2, '%s\n', newstring);
else
fprintf(fid2, '%s', line);
end
line = fgets(fid1);
i = i + 1;
end
st = fclose(fid1);
if st == -1
error(['Cannot close ' filename '.'])
end
st = fclose(fid2);
if st == -1
error(['Cannot close ' tempfilename '.'])
end
if i < lineno
warning(['File ' filename ' has fewer than ' int2str(lineno) 'lines.']);
delete(tempfilename)
else
movefile(tempfilename, filename, 'f')
end

2 Comments

values of a and b are not fixed (they are changeable according to iteration processes before reading the text file and changing the values of a & b in lines 131 &132), therefore I can't assume a & b as string
patchline('test.txt', sprintf('a = %d',a), 132)

Sign in to comment.

you'll need to use fopen, fgetl, and fprintf() to do this. To accomplish this is that you'll need to open the file in read/write mode and jump to the first specific line (in your example 131) and do your edit by overwriting that line. Then all subsequent lines will have to be rewritten. You cannot just make an edit to the raw file like you would in a text editor. otherwise you'll either end up with additional spaces or lines that are "overlapping".
For example your original line of "a= 10" is say 5 characters long before the new line + carriage return (\n\r). but you want to replace it with "a= 5" which is only 4 characters long. this wouldn't be too big of an issue since you can probably live with an extra " " somewhere. The issue comes in when you are trying to put something like "a= 123" which is longer than the original. Since the inserted text doesn't move all the items below it you'll be writing into the next line's data.

4 Comments

l assumed the whole line 131 as string and then I used "strrep" to change 'a=10' to 'a=5'
s = strrep(s, 'a = 10', 'a=5'); without any problem
But, the value of a is changeable according to an iteration operation and I cant fix it to 5
help please
since you're reading it line by line strrep isn't going to get you anything that replacing the whole string. strrep replaces all occurrences of the string with another string. Also as far as i know strrep only replaces a subset of the original string when it is loaded into the workspace and not in a file.
teststr = ['abcabcabc']
strrep(teststr,'a','z')
%returns ['zbczbczbc']
so you already have teststr you already know what it should be.
Since you do not explain how it is changeable here is the structure of reading and skipping to lineX.
fid = fopen('myfile.txt')
linenum = 0;
while ~eof(fid)
tline = fgetl(fid);
linenum = linenum+1;
if linenum>=131
if linenum==131
fprintf(fid,'a = %f',%whatever you want it to swap to)
elseif linenum==132
fprintf(fid,'b = %f',%whatever you want it to swap to)
else
fprintf(fid,tline)
end
end
I don't have matlab with me to check the code above with an example but with the documentation on fprintf and other functions it will get you where you need to go.
I tried it but I got the same original txt file without any change to the values of a & b
fid = fopen('test.txt');
linenum = 0;
aa=5;
bb=60;
while ~feof(fid)
tline = fgetl(fid);
linenum = linenum+1;
if linenum>=131
if linenum==131
fprintf(fid,'a = %d',aa);
elseif linenum==132
fprintf(fid,'b = %d',bb);
else
fprintf(fid,tline);
end
end
end
fclose(fid);
You should always be testing for end of file after you read, not before you read. feof() is not predictive. feof() is not true until you make a read that fails.

Sign in to comment.

Categories

Tags

Community Treasure Hunt

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

Start Hunting!