I'd like to replace a string in a text file in MATLAB.
To read the specified line I used the code :
fid = fopen(file_name, 'r');
tt = textscan(fid, '%s', 1, 'delimiter', '\n', 'headerlines', i);
ttt = str2num(tt{1}{1});
where file_name is the name of my file and ttt is a cell array that contains the i-th string converted in integer.
For example, ttt = 1 2 3 4 5 6 7 8
Now, I'd like to change ttt with ttt = 0 0 0 0 0 0 0 0
and write the new ttt at the i-th line in the file.
Does anybody have an idea to handle this?
A possible implementation is
fid = fopen('input.txt', 'r+');
tt = textscan(fid, '%s', 1, 'delimiter', '\n', 'headerlines', 1); % scan the second line
tt = tt{1}{1};
ttt = str2num(tt); %parse all the integers from the string
ttt = ttt*0; %set all integers to zero
fseek(fid, length(tt), 'bof'); %go back to the start of the parsed line
format = repmat('%d ', 1, length(ttt));
format = format(1:end-1); %remove the trailing space
fprintf(fid, format, ttt); %overwrite the text in the file
fclose(fid); %close the file
This will change the input.txt from:
your first line
1 2 3 4 5 6 7 8
5 5 5 5 5 5 5 5
into
your first line
0 0 0 0 0 0 0 0
5 5 5 5 5 5 5 5
Note that it is only possible to overwrite existing characters in the file. If you want to insert new characters, you have two rewrite the full file or at least from the position where you want to insert your new characters.
Or use something like this ...
fid = fopen('input_file.txt', 'r');
f = fread(fid, '*char')';
fclose(fid);
f = strrep(f, ' ', ''); % to remove
f = strrep(f, ' ', ' .'); % to replace
% save into new txt file
fid = fopen('output_file.txt', 'w');
fprintf(fid, '%s', f);
fclose(fid);
Related
Do you have any idea about this problem?
Question:
Write and execute an LC-3 assembly program which concatenates two strings. The first string begins at memory address x4000, and the second string begins at memory address x5000. Strings always terminate with a 0.
Example:Before your program executes:
M[x4000] = 5 M[x5000] = 6
M[x4001] = 2 M[x5001] = 1
M[x4002] = 8 M[x5002] = 8
M[x4003] = 4 M[x5003] = 0
M[x4004] = 0
After your program executes:
M[x4000] = 5 M[x5000] = 6
M[x4001] = 2 M[x5001] = 1
M[x4002] = 8 M[x5002] = 8
M[x4003] = 4 M[x5003] = 0
M[x4004] = 6 M[x4005] = 1
M[x4006] = 8 M[x4007] = 0
Here's an idea: write a loop to locate the address of the first zero word starting from 0x4000. Once you've found that, write another loop that will copy words from 0x5000 and further to that address, terminating once the zero byte is copied.
how to add/remove, number or range of numbers from a file and reorganize the range
for example in file
$ cat test.in
cn[01-10]
cn01
cn[01,02,07-09]
cn[01-02]
Requirement to remove cn01 and cn05
desired output
$ cat test.in
cn[02-04,06-10]
cn[02,07-09]
cn[02]
Here's how to expand your lists and ranges of values into individual values:
$ cat tst.awk
function expand(exprStr,valsArr, i,terms,term,range,val,numVals) {
gsub(/cn|[][]/,"",exprStr)
delete valsArr
# exprStr = 01,02,07-09
split(exprStr,terms,/,/)
for (i=1; i in terms; i++) {
# terms[1]=01, [2]=02, [3]=07-09
term = terms[i]
split(term,range,/-/)
range[2] = (2 in range ? range[2] : range[1])
for (val=range[1]; val<=range[2]; val++) {
# range[1]=07, [2]=09
valsArr[++numVals] = sprintf("%02d",val)
}
}
}
{
print "--------", $0
expand($0,arr)
for (i=1; i<=length(arr); i++) {
print i, "cn"arr[i]
}
}
.
$ awk -f tst.awk file
-------- cn[01-10]
1 cn01
2 cn02
3 cn03
4 cn04
5 cn05
6 cn06
7 cn07
8 cn08
9 cn09
10 cn10
-------- cn01
1 cn01
-------- cn[01,02,07-09]
1 cn01
2 cn02
3 cn07
4 cn08
5 cn09
-------- cn[01-02]
1 cn01
2 cn02
Now just delete the values you don't want from the array and essentially do the reverse to recombine into your input format.
Example in Python 3
import re
from itertools import groupby
inp = """cn[01-10]
cn01
cn[01,02,07-09]
cn[01-02]"""
rem = {1, 5}
def parse_lst(lst_str):
for group in lst_str.split(','):
if '-' in group:
first, last = group.split('-')
yield from range(int(first), int(last)+1)
else:
yield int(group)
def format_range(range_):
ranges = []
for k, g in groupby(enumerate(range_), lambda x: x[0]-x[1]):
group = [n for i, n in g]
ranges.append((group[0], group[-1]))
if not ranges:
return
print("cn[" + ','.join(
'{:02d}'.format(first) if first == last else
'{:02d}-{:02d}'.format(first, last) for
first, last in ranges
) + ']')
for line in inp.splitlines():
lst_match = re.search(r'\[(.*)\]', line)
if lst_match:
range_ = parse_lst(lst_match.group(1))
else:
range_ = (int(line[2:]),)
filtered = sorted(set(range_) - rem)
format_range(filtered)
prints
cn[02-04,06-10]
cn[02,07-09]
cn[02]
I have a 3-year data in a string tableformat.txt. Three of its lines are given below:
12-13 Jan -10.5
14-15 Jan -9.992
15-16 Jan -8
How to change the 3rd column (-10.5, -9.992 and -8) of string to be (-10.500, -9.992 and -8.000) of number?
I have made the following script:
clear all; clc;
filename='tableformat.txt';
fid = fopen(filename);
N = 3;
for i = [1:N]
line = fgetl(fid)
a = line(10:12);
na = str2num(a);
ma(i) = na;
end
ma
which gives:
ma = -1 -9 -8
When I did this change: a = line(10:15);, I got:
Error message: Index exceeds matrix dimensions.
This will work for you.
clear all;
clc;
filename='tableformat.txt';
filename2='tableformat2.txt';
fid = fopen(filename);
fid2 = fopen(filename2,'w');
formatSpec = '%s %s %6.4f\n';
N = 3;
for row = [1:N]
line = fgetl(fid);
a = strsplit(line,' ');
a{3}=cellfun(#str2num,a(3));
fprintf(fid2, formatSpec,a{1,:});
end
fclose(fid);
fclose(fid2);
I would like to read my measurement data from a text file. The data have e.g. following form:
0 0.0531139
0.000157095 0.306123
0.000314191 0.133868
0.000471286 0.29799
0.000628381 0.0182098
0.000785477 0.121222
0.000942572 0.32111
0.00109967 0.0267326
0.00125676 0.49554
0.00141386 0.433729
My code is as follows:
SUBROUTINE test(name)
implicit none
character :: name*(*)
real*8,allocatable, dimension(:,:) :: measMatrix
integer :: i,
& nrcols
nrcols = 2
nrrows = 10
allocate(measMatrix(nrcols,nrrows))
open(unit = 20, file = Dateiname, status = 'old', action = 'read')
do i = 1, nrrows
read(20,*) measMatrix(i,1:nrcols)
end do
close(20)
open(unit = 10, file = 'Test4.txt')
do i = 1,nrrows
write(10,777) (measMatrix(i,j), j = 1,nrcols)
end do
close(10)
777 format(F12.9,4X,F12.9)
deallocate(measMatrix)
END
However, the output is wrong:
0.000000000 0.000314191
0.000157095 0.000471286
0.000314191 0.000628381
0.000471286 0.000785477
0.000628381 0.000942572
0.000785477 0.001099670
0.000942572 0.001256760
0.001099670 0.001413860
0.001256760 0.495540000
0.001413860 0.433729000
What am I doing wrong ? :(
Thanks in advance for the help.
The first dimension is the fasted changing one, and the one contiguous in memory.
So in memory space your (10,2) is laid out as:
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
10 20
Maybe you want this:
nrrows = 10
nrcols = 2
allocate(measMatrix(10,2))
do i = 1, nrrows
read(20,*) measMatrix(i,:)
end do
...
do i = 1, nrrows
write(10,777) measMatrix(i,:)
end do
I prefer this:
integer :: Crnt_Row, Crnt_Col
nrrows = 10
nrcols = 2
allocate(measMatrix(10,2))
WRITE(*,*)'Shape(measMatrix)=',SHAPE(measMatrix)
do CurrRow = 1, nrrows
read(20,*) measMatrix(CurrRow,:)
end do
...
do CurrRow = 1, nrrows
write(10,777) measMatrix(CurrRow,:)
end do
Using IMPLICIT NONE will also help along the lines of what #d_1999 mentioned.
I have strings of 32 chars in a file (multiple lines).
What I want to do is to make a new file and put them there by making columns of 4 chars each.
For example I have:
00000000000FDAD000DFD00ASD00
00000000000FDAD000DFD00ASD00
00000000000FDAD000DFD00ASD00
....
and in the new file, I want them to appear like this:
0000 0000 000F DAD0 00DF D00A SD00
0000 0000 000F DAD0 00DF D00A SD00
Can you anybody help me? I am working for hours now and I can't find the solution.
First, open the input file and read the lines as strings:
infid = fopen(infilename, 'r');
C = textscan(infid, '%s', 'delimiter', '');
fclose(infid);
Then use regexprep to split the string into space-delimited groups of 4 characters:
C = regexprep(C{:}, '(.{4})(?!$)', '$1 ');
Lastly, write the modified lines to the output file:
outfid = fopen(outfilename, 'w');
fprintf(outfid, '%s\n', C{:});
fclose(outfid);
Note that this solution is robust enough to work on lines of variable length.
Import
fid = fopen('test.txt');
txt = textscan(fid,'%s');
fclose(fid);
Transform into a M by 28 char array, transpose and reshape to have a 4 char block on each column. Then add to the bottom a row of blanks and reshape back. Store each line in a cell.
txt = reshape(char(txt{:})',4,[]);
txt = cellstr(reshape([txt; repmat(' ',1,size(txt,2))],35,[])')
Write each cell/line to new file
fid = fopen('test2.txt','w');
fprintf(fid,'%s\r\n',txt{:});
fclose(fid);
Here's one way to do it in Matlab:
% read in file
fid = fopen('data10.txt');
data = textscan(fid,'%s');
fclose(fid);
% save new file
s = size(data{1});
newFid = fopen('newFile.txt','wt');
for t = 1:s(1) % format and save each row
line = data{1}{t};
newLine = '';
index = 1;
for k = 1:7 % seven sets of 4 characters
count = 0;
while count < 4
newLine(end + 1) = line(index);
index = index + 1;
count = count + 1;
end
newLine(end + 1) = ' ';
end
fprintf(newFid, '%s\n', newLine);
end
fclose(newFid);