I am doing an operation to get a matrix M_T. This matrix is to be saved into a text file. And this text file is to be again utilized as the primary data file. This has to be repeated for 100 times. Also in the end I want to save all the data in the 100 text files generated into a single text file named final_result.txt. I am not able to figure out how to save the different text files in different names within the loop. I tried by writing the following code. But it is showing errors.
for k=1:100
fid = fopen('data1.txt');
A = textscan(fid, '%f %f %f ') ;
%read the file
a = A{1};
b = A{2};
c = A{3};
p=[a b c];
p_t=p.';
M=rotationMatrix*p_t;
M_T=M.';
fid = fopen('data1.txt', 'wt');
fprintf(fid,' %f\t %f\t %f\n',M_T);
fclose(fid);
textfilename = ['result' num2str(k) '.txt'];
fid1 = fopen('result'k '.txt', 'wt');
fprintf(fid1,' %f\t %f\t %f\n',M_T);
fclose(fid1);
end
Try this
textfilename = ['result' num2str(k) '.txt'];
fid1 = fopen(textfilename, Write);
...
this should generate a separate file resultk.txt where k = 1,...,100.
Also, you are opening the input file twice but only closing it once. I think it would be better to close the file when you open it for reading before again opening it for writing.
If this doesn't solve the problem, try posting the specific error messages you get.
To output all files to a master file, do this before the loop starts
fidresult = fopen('final_result.txt', Write);
then at each iteration
fprintf(fidresult,' %f\t %f\t %f\n',M_T);
then after the loop is finished
fclose(fidresult)
This should output your matrix at each iteration to the master result file in addition to creating an individual file for each loop iteration
Related
I have several .txt files of 2 columns, that I’d like to import and use the second column for subsequent operations. My text files are name as: profileA1.txt, profileA2.txt, etc… and my variables corresponding to the data of the second column are named in the subsequent code are A1, A2, A3, etc…
The code works but currently I have to open manually each .txt file with the Import data wizard, change the name of the second column and click on the import the selection. I tried to write a code (see below) to automatize these steps but it doesn’t work? Anyone has any idea to fix this code?
Thanks
for k = 1:5
myfilename = sprintf('profileA%d.txt', k);
mydata = importdata(myfilename);
Aloop = ['A' num2str(k)];
A{k} = load(myfilename.data(:,2), k);
end
You're example is a little off because you convert myfilename from a character array to a structure magically. I would approach this by reading the entire text file into a cell array of characters then using cellfun and textscan to read in the columns. Like this:
function C = ReadTextFile(infile)
if (exist(infile, 'file') ~= 2)
error('ReadTextFile:INFILE','Unknown file: %s.\n', infile);
end
fid = fopen(infile, 'r');
C = textscan(fid, '%s', 'delimiter','\n');
C = C{1};
fclose(fid);
end
% assign an output file
outFile = 'SomeRandomFile.mat';
for k = 1:5
C = ReadTextFile(sprintf(‘profileA%d.txt’, k));
val = cell2mat(cellfun(#(x) textscan(x, '%*f %f','CollectOutput',1),C));
varName = sprintf('A%d', k);
assignin('base', varName, val);
save(outFile, varName, '-append')
end
You can skip the whole reading as a character array first but I have that function already so I just reused it.
I have two text files: file1.txt & file2.txt
Contents of file1.txt:
Required contents of file;
Required contents of file;
Required contents of file;
Required contents of file;
Required contents of file;
My old contents(1);
My old contents(2);
My old contents(3);
My old contents(4);
Required contents of file;
Required contents of file;
Required contents of file;
Required contents of file;
Contents of file2.txt:
My new var(1);
My new var(2);
My new var(3);
My new var(4);
I have an updateFile.m function: which is trying to replace the old contents from file1.txt with new var respectively
function updateFile(file)
% Read the new contents
fid = fopen('file2.txt', 'r');
c1 = onCleanup(#()fclose(fid));
newVars = textscan(fid,'%s','Delimiter','\n');
newVars = newVars{1};
% Save the testfile in to a cellaray variable
fid = fopen(file, 'r');
c2 = onCleanup(#()fclose(fid));
oldContent = textscan(fid,'%s','Delimiter','\n');
% Search for specific strings
oldContentFound = strfind(oldContent{1},'My old contents(1);');
oldContentRowNo = find(~cellfun('isempty',oldContentFound));
% Move the file position marker to the correct line
fid = fopen(file, 'r+');
c3 = onCleanup(#()fclose(fid));
for k=1:(oldContentRowNo-1)
fgetl(fid);
end
% Call fseek between read and write operations
fseek(fid, 0, 'cof');
for idx = 1:length(newVars)
fprintf(fid, [newVars{idx} '\n']);
end
end
The problem I am facing is that, file1.txt still contains some old contents which are not required. Any help would be appreciated.
Thanks
You can add some characters into the file but you can't remove some. You have to erase your file with a new one that has the correct content.
Here is a rewriting of your function that does the job:
function updateFile(file)
% Read the new contents
fid = fopen('file2.txt', 'r');
newVars = textscan(fid,'%s','Delimiter','\n');
fclose(fid);
newVars = newVars{1};
% Read the old content
fid = fopen(file, 'r');
f1 = textscan(fid, '%s', 'Delimiter', '\n');
fclose(fid);
f1 = f1{1};
% Find pattern start line
[~,k] = ismember('My old contents(1);', f1);
% Replace pattern
for i = 1:numel(newVars)
f1{k+i-1} = newVars{i};
end
% Replace initial file
fid = fopen(file, 'w');
cellfun(#(x) fprintf(fid, '%s\n', x), f1);
fclose(fid);
Best,
File access is inherently byte-based. There's no such thing as inserting or deleting content at the middle of a file. In most cases, the easiest approach is to edit the content in memory, then rewrite the entire file.
In your case, after reading the input file, find the start and end rows in the cell array, and simply replace them with the new data. Then open your file again for normal writing, and output the entire cell array.
all,
I am writing a matlab program to read in text data and rearrange it. Now I am meeting with a new problem.
When I am writing data out to csv file, there are randomly missing data noted as ******, as shown below causing my program to terminate.
2055 6 17 24.2 29.57 7.02****** 0.99 2.65 2.73 4.09 0.11
Any one can help me with a small program to loop through all the text files in the folder, and replace the consecutive stars, with 0.00? The stars are always in columns 33 to 38, occupying 6 spaces. I want it to be changed to be two spaces followed by 0.00.
Thanks,
James
For a given text file, you can read it into memory, replace the asterisks with the desired text, and then overwrite the original text file:
filename = 'blah.txt'
% Read it into memory
fid = fopen(filename, 'r');
scanned_fields = textscan(fid, '%s', 'Delimiter','\n');
fclose(fid);
% The first (and only) field of textscan will be our cell array of text
lines = scanned_fields{1};
% Replace the asterisks with the desired text
lines = strrep(lines, '******', ' 0.00');
% Overwrite the original file
fid = fopen(filename, 'w');
fprintf(fid, '%s\n', lines{:});
fclose(fid);
To do this for all of the text files in your directory, you can use dir to get a list of files in your current directory that end in ".txt":
files = dir('*.m');
filenames = {files.name};
And then loop over the files:
for ii = 1:length(filenames)
filename = filenames{ii};
% Read it into memory
fid = fopen(filename, 'r');
scanned_fields = textscan(fid, '%s', 'Delimiter','\n');
fclose(fid);
lines = scanned_fields{1};
% Replace the asterisks with the desired text
lines = strrep(lines, '******', ' 0.00');
% Overwrite the original file
fid = fopen(filename, 'w');
fprintf(fid, '%s\n', lines{:});
fclose(fid);
% Go on to the next file
end
And of course, I would recommend creating a backup copy of this directory before running this, just in case something unexpected comes up.
I have 2 instances of Matlab running. While the first is writing data to a .txt file, the other is reading that data.
Is there a way to verify that the .txt file is being accessed and accordingly throw an exception/error?
I found that the second Matlab instance reads the data anyways but generates an error such as Horzcat etc while that .txt file was being updated as well.
fName = 'Test.txt' ;
% Matlab Instance1
mat = 1 + (2-1)*randn(100000,5) ; mat = mat.' ;
[fid, fMsg] = fopen(fName, 'at') ;
if fid~=-1, fprintf(fid, '%.10f\t%.10f\t%.10f\t%.10f\t%.10f\r\n', mat(:)) ; end
fclose(fid);
% Matlab Instance2
fid = fopen(fName);
C = textscan(fid, '%f %f %f %f %f', 'Delimiter', '\t');
C=cell2mat(C);
fclose(fid);
On the writing instance create a file called 'busyWriting.bla' before opening the file for writing, delete this file after you are done writing. And on the reading instance enclose everything with the clause if(~exist('busyWriting.bla','file')) ... end
In Matlab, after creating a certain number of lines and printing them to a file, I have the need to delete a line and rewrite the rest of the data to that same file. When I do so, the new data overwrites the previous data, but since the data is shorter than the original, there are still remnants of the original data. Does anyone have any idea what the best/most efficient way to delete that extra data is?
Here is a simplified example of what I'm trying to do:
fid = fopen('file.txt','w');
for i=1:10
fprintf(fid,'%i\r\t',i);
end
frewind(fid);
for i=3:5
fprintf(fid,'%i\r\t',i);
end
fprintf(fid,'EOF');
fclose(fid);
I've looked all over, but I can't seem to find the solution to my question. Any suggestions?
Without using any temp files, you can do the following:
fid = fopen('file.txt', 'wt');
for i=1:10
fprintf(fid, '%i\n', i);
end
frewind(fid);
for i=3:5
fprintf(fid, '%i\n', i);
end
pos = ftell(fid); % get current position in file
fclose(fid);
% read from begining to pos
fid = fopen('file.txt', 'r');
data = fread(fid, pos);
fclose(fid);
% overwite file with data read
fid = fopen('file.txt', 'w');
fwrite(fid, data);
fclose(fid);
Printing "EOF" won't work - nice try!
There are Unix system calls truncate and ftruncate that will do that, given either a file descriptor (truncate) or handle (ftruncate) in the first argument and a desired length in the second.
I'd try and see if Matlab supports ftruncate. Failing that... if worst came to worst you could copy-write the file to a new file, stopping and closing the new file when you hit what you consider the end of data.
To follow up on Carl Smotricz's suggestion of using two files, you can use MATLAB's DELETE and MOVEFILE commands to avoid system calls:
fid = fopen('file.txt','wt');
for i=1:10
fprintf(fid,'\t%i\r',i);
end
fclose(fid);
fid = fopen('file.txt','rt');
fidNew = fopen('fileNew.txt', 'wt');
for i = 1:2
s = fgetl(fid);
fprintf(fidNew, '%s\r', s);
end
for i=4:10
fprintf(fidNew, '\t%i\r', i);
end
fclose(fid);
fclose(fidNew);
delete('file.txt');
movefile('fileNew.txt', 'file.txt')