Here is the code that I am using;
files2 = dir('X_*.txt');
for kty=1:p
fidF = fopen(['X(A)_' num2str(kty) '.txt'], 'w');
for i = 1:length(files2)
fid = fopen(files2(i).name);
while(~feof(fid))
string = fgetl(fid)
fprintf(fidF, '%s', string)
end
fclose(fidF);
end
end
P equal to 90, because there have 90 different X text file which include different angles.The new X(A) text files should be 90 different files.
The code is used for getting rid of this second line and it's working.
The thing I want to ask is that when I use this code it creates X(A) text files (90 files) but all include X_1 files angle variable but it should be;
X_1 > X(A)_1 (each variable should transfer to new file.)
(X_65 > X(A)_65)
X_2 > X(A)_2
...
...
How can I fix the code?
files2 = dir('angle_*.txt');
for i = 1:length(files2)
fidF = fopen(['angle(A)_' num2str(i) '.txt'], 'w');
fid = fopen(files2(i).name);
while(~feof(fid))
string = fgetl(fid)
fprintf(fidF, '%s', string)
end
fclose(fidF);
fclose(fid);
end
result are
angle_1=272 angle(A)_1=272
angle_2=276 angle(A)_2=308
angle_3=280 angle(A)_3=312
angle_4=284 angle(A)_4=316
angle_5=288 angle(A)_5=320
angle_6=292 angle(A)_6=324
angle_7=296 angle(A)_7=328
angle_8=300 angle(A)_8=332
angle_9=304 angle(A)_9=336
angle_10=308 angle(A)_10=340
angle_11=312 angle(A)_11=344
angle_12=316 angle(A)_12=348
angle_10 variable goes to angle(A)_2 variable and its copy in this order.
In order to have your input and output files match, you need to remove one of the for loops and have X(A)_#.txt match files2(#).name:
files2 = dir('X_*.txt');
for i = 1:length(files2)
fid = fopen(files2(i).name);
fNum = regexp(files2(i).name, '([0-9]*)', 'match');
fidF = fopen(['X(A)_' fNum{1} '.txt'], 'w');
while(~feof(fid))
string = fgetl(fid)
fprintf(fidF, '%s', string)
end
fclose(fidF);
fclose(fid);
end
I've removed the loop from 1:p and used the loop over the number of input files with i as the loop variable. i is used for both the output file name and the index to the input file list.
Related
In a main m-file I have
conformal = maketform('custom', 2, 2, [], #conformalInverse_0001, []);
used in imtransform that refers to the function defined in conformalInverse_0001.m:
function U = conformalInverse_0001(X, ~)
%#codegen
U = [zeros(size(X))];
Z = complex(X(:,1),X(:,2));
W = 1./(4.*Z.^2-1);
U(:,2) = imag(W);
U(:,1) = real(W);
How can I get the string '1./(4.*Z.^2-1)' in the main program?
I found a way to solve it, but it's not so elegant...
Assume conformalInverse_0001.m is a file in your folder.
You can parse the file as a text file, and search for your formula.
Example:
Assume you know the location is 5'th line in file, and start with W =.
You can use something like the following code to read '1./(4.*Z.^2-1)' in the main program:
%Open file for reading.
fid = fopen('conformalInverse_0001.m', 'r');
%Read 5 lines.
s = textscan(fid, '%s', 5, 'delimiter', '\n');
fclose(fid);
%Get the 5'th line.
s = s{1}(5);
%Convert cell array to string.
s = s{1};
%Get characters from the 5'th character to one char before end of string.
s = s(5:end-1)
Result: s = 1./(4.*Z.^2-1)
You can check textscan documentation for finding more elegant solution.
I'm not sure I fully understand the problem here, but what about adding into your conformalInverse_0001 function something like:
str = '1./(4.*Z.^2-1)';
save('temp_str','str') % or whatever data that you want to save from it
and then adding in your main file:
load('str.mat')% or you can use 'impordata'
where you want to extract it.
I have hacked two solutions with textscan: first knowing the line number and second searching the line that starts with substring 'W = '
% read line line_num = 5 and process string
f_id = fopen(conformalInverse_m_path);
conformalInverse_cell = textscan(f_id,'%s','delimiter','\n'); %disp(conformalInverse_cell); % {68×1 cell}
func_string = conformalInverse_cell{1}{line_num}; disp(func_string); % W = 1./(4.*Z.^2-1); OK
func_string_2=func_string(5:end-1); disp(func_string_2); % 1./(4.*Z.^2-1); OK
% read first line that starts with substring 'W = ' and process string
W_string = 'W = ';
for i=1:100
func_string = conformalInverse_cell{1}{i};
Firt4=func_string(1:4); %disp(['i = ', num2str(i), ': First4 = ', Firt4]);
if strcmp(Firt4,W_string) == 1; line_nr = i; break; end;
end
func_string_2 = conformalInverse_cell{1}{line_nr};
func_string_3=func_string_2(5:end-1);
Maybe the question is strange but anyway....
How can i read the value (string or number) of the variable number_of_plots or color? (i want to use the variable/array diagram options to solve this problem)
My Code:
diagramoptions = [];
wholecontent = fileread('aaa.txt')
sections = regexp(wholecontent, '\*+([^*]+)\*+([^*]+)', 'tokens')
for section = sections
switch(strtrim(section{1}{1}))
case 'Diagram Options' %Diagram Options -> siehe meine Gliederung im .txt file
keyvalues = regexp(section{1}{2}, '([^\n\r=]+)=([^\n\r=]+)', 'tokens')%\n -> new line; \r carriage return
diagramoptions = cell2table(vertcat(keyvalues{:}), 'VariableNames', {'Key', 'Value'})
otherwise
warning('Unknown section: %s', section{1}{1})
end
end
openvar diagramoptions
My Input "aaa.txt":
******************* Diagram Options****************
number_of_plots=4
header=Number of cycles
color=red
xlabel= RPM
ylabel= degree
Here's a naive way of doing it... It doesn't scale well and it does unnecessary work.. But it's something for you to build upon.
fileId = fopen('test.txt');
c = textscan(fileId, '%s', 'Delimiter', '=');
fclose(fileId);
for i = 1: length(c{1,1})
if (strcmp(c{1,1}{i,1}, 'number_of_plots'))
number_of_plots = c{1,1}{i+1,1};
elseif strcmp(c{1,1}{i,1}, 'color')
color = c{1,1}{i+1,1};
end
end
So, read in the file and delimit at = makes you know that any match on e.g. number_of_plots is in the next row. So just loop through and pick it out.
You can use the function eval in order to run a .txt file as it was a .m file:
fid = fopen('aaa.txt') %open the file
tline = fgetl(fid); %read the first line
while ischar(tline)
if ~isempty(strfind('tline','number_of_plots')) | ~isempty(strfind('tline','color='))
try %if it's possible matlab execute this line
eval(tline)
end
end
tline = fgetl(fid); %read the next line
end
fclose(fid)
But in this case you need to add some quotation marks to your aaa.txt so that matlab can create the variables:
******************* Diagram Options****************
number_of_plots=4
header='Number of cycles'
color='red'
xlabel='RPM'
ylabel='degree'
I have a data file that contains parameter names and values with an equal sign in between them. It's like this:
A = 1234
B = 1353.335
C =
D = 1
There is always one space before and after the equal sign. The problem is some variables don't have values assigned to them like "C" above and I need to weed them out.
I want to read the data file (text) into a cell and just remove the lines with those invalid statements or just create a new data file without them.
Whichever is easier, but I will eventually read the file into a cell with textscan command.
The values (numbers) will be treated as double precision.
Please, help.
Thank you,
Eric
Try this:
fid = fopen('file.txt'); %// open file
x = textscan(fid, '%s', 'delimiter', '\n'); %// or '\r'. Read each line into a cell
fclose(fid); %// close file
x = x{1}; %// each cell of x contains a line of the file
ind = ~cellfun(#isempty, regexp(x, '=\s[\d\.]+$')); %// desired lines: space, numbers, end
x = x(ind); %// keep only those lines
If you just want to get the variables, and reject lines that do not have any character, this might work (the data.txt is just a txt generated by the example of data you have given):
fid = fopen('data.txt');
tline = fgets(fid);
while ischar(tline)
tmp = cell2mat(regexp(tline,'\=(.*)','match'));
b=str2double(tmp(2:end));
if ~isnan(b)
disp(b)
end
tline = fgets(fid);
end
fclose(fid);
I am reading the txt file line by line, and using general expressions to get rid of useless chars, and then converting to double the value read.
I'm attempting to count the number of letters in a text file, but unfortunately I keep getting stuck if numbers are involved.
So far I have been able to deal with letters and symbols, but unfortunately the ischar function doesn't help me when it comes to numbers.
function ok = lets(file_name)
fid = fopen(file_name, 'rt');
if fid < 0
ok = -1;
end
C = [];
D = [];
oneline = fgets(fid);
while ischar(oneline)
C = oneline(isletter(oneline));
W = length(C);
D = [D ; W];
oneline = fgets(fid);
end
total = 0;
for i = 1:length(D)
total = D(i) + total;
end
ok = total;
How can I deal with counting letters if there are also numbers in a text file?
I approached the problem the following way:
function ok = lets(file_name)
file = memmapfile( file_name, 'writable', false );
lowercase = [65:90];
uppercase = [97:122];
data = file.Data;
ok = sum(histc(data,lowercase)+histc(data,uppercase));
end
I mapped the file to memory using the memmapfile function and compared the data with the character encodings from this ASCII table. Lower case letters are represented by [65:90] and upper case letters by [97:122]. By applying the histc function, I got the frequency in which each letter appeared in the file. The total number of letters is given by adding all the frequencies up.
Note that I called histc twice to avoid having a bin from 90 to 97, which would count the []^_` characters.
I applied the function to a sample file called sample.txt containing the following lines:
abc23D&f![
k154&¨&skj
djaljaljds
Here is my output:
>> lets('sample.txt')
Elapsed time is 0.017783 seconds.
ans =
19
Edit:
Outputting ok=-1 for problems reading file:
function ok = lets(fclose(fid);file_name)
try
file = memmapfile( file_name, 'writable', false );
catch
file=[];
ok=-1;
end
if ~isempty(file)
lowercase = [65:90];
uppercase = [97:122];
data = file.Data;
ok = sum(histc(data,lowercase)+histc(data,uppercase));
end
end
With fopen approach, since you get the ok=-1 "by default":
function ok = lets(file_name)
fid = fopen(file_name, 'rt');
if fid < 0
ok = -1;
else
celldata=textscan(fid,'%s');
fclose(fid);
lowercase = [65:90];
uppercase = [97:122];
data = uint8([celldata{1}{:});
ok = sum(histc(data,lowercase)+histc(data,uppercase));
end
end
I think you are making this a lot more complected than it needs to be, just use isletter like you had and then use length.
function ok = lets(file_name)
%Original code as you had it
fid = fopen(file_name, 'rt');
if fid < 0
ok = -1;
end
%Initialize length
ok = 0;
%Get first line
oneline = fgets(fid);
%While line isn't empty
while oneline ~= -1
%remove everythin that's not a letter
oneline(~isletter(oneline)) = [];
%Add number of letters to output
ok = ok + length(oneline);
%Get next line
oneline = fgets(fid);
end
end
I used the input file,
Ar,TF,760,2.5e-07,1273.14,4.785688323049946e+24,24.80738364864047,37272905351.7263,37933372595.0276
Ar,TF,760,5e-07,1273.14,4.785688323049946e+24,40.3092219226107,2791140681.70926,2978668073.513113
Ar,TF,760,7.5e-07,1273.14,4.785688323049946e+24,54.80989010679312,738684259.1671219,836079550.0157251
and got 18, this counts the e's in the numbers, do you want these to be counted?
From the beginning.
I have data in a csv file like:
La Loi des rues,/m/0gw3lmk,/m/0gw1pvm
L'Étudiante,/m/0j9vjq5,/m/0h6hft_
The Kid From Borneo,/m/04lrdnn,/m/04lrdnt,/m/04lrdn5,/m/04lrdnh,/m/04lrdnb
etc.
This is in UTF-8 format. I import this file as follows (taken from somewhere else):
feature('DefaultCharacterSet','UTF-8');
fid = fopen(filename,'rt'); %# Open the file
lineArray = cell(100,1); %# Preallocate a cell array (ideally slightly
%# larger than is needed)
lineIndex = 1; %# Index of cell to place the next line in
nextLine = fgetl(fid); %# Read the first line from the file
while ~isequal(nextLine,-1) %# Loop while not at the end of the file
lineArray{lineIndex} = nextLine; %# Add the line to the cell array
lineIndex = lineIndex+1; %# Increment the line index
nextLine = fgetl(fid); %# Read the next line from the file
end
fclose(fid); %# Close the file
This makes an array with the UTF-8 text within it. {3x1} array:
'La Loi des rues,/m/0gw3lmk,/m/0gw1pvm'
'L''Étudiante,/m/0j9vjq5,/m/0h6hft_'
'The Kid From Borneo,/m/04lrdnn,/m/04lrdnt,/m/04lrdn5,/m/04lrdnh,/m/04lrdnb'
Now the next part separates each value into an array:
lineArray = lineArray(1:lineIndex-1); %# Remove empty cells, if needed
for iLine = 1:lineIndex-1 %# Loop over lines
lineData = textscan(lineArray{iLine},'%s',... %# Read strings
'Delimiter',',');
lineData = lineData{1}; %# Remove cell encapsulation
if strcmp(lineArray{iLine}(end),',') %# Account for when the line
lineData{end+1} = ''; %# ends with a delimiter
end
lineArray(iLine,1:numel(lineData)) = lineData; %# Overwrite line data
end
This outputs:
'La Loi des rues' '/m/0gw3lmk' '/m/0gw1pvm' [] [] []
'L''�tudiante' '/m/0j9vjq5' '/m/0h6hft_' [] [] []
'The Kid From Borneo' '/m/04lrdnn' '/m/04lrdnt' '/m/04lrdn5' '/m/04lrdnh' '/m/04lrdnb'
The problem is that the UTF-8 encoding is lost on the textscan (note the question mark I now get whereas it was fine in the previous array).
Question: How do I maintain the UTF-8 coding when it translates the {3x1} array into a 3xN array.
I can't find anything on how to keep UTF-8 encoding in a textscan of an array already in the workspace. Everything is to do with importing a text file which I have no problems with - it is the second step.
Thanks!
Try the following code:
%# read whole file as a UTF-8 string
fid = fopen('utf8.csv', 'rb');
b = fread(fid, '*uint8')';
str = native2unicode(b, 'UTF-8');
fclose(fid);
%# split into lines
lines = textscan(str, '%s', 'Delimiter','', 'Whitespace','\n');
lines = lines{1};
%# split each line into values
C = cell(numel(lines),6);
for i=1:numel(lines)
vals = textscan(lines{i}, '%s', 'Delimiter',',');
vals = vals{1};
C(i,1:numel(vals)) = vals;
end
The result:
>> C
C =
'La Loi des rues' '/m/0gw3lmk' '/m/0gw1pvm' [] [] []
'L'Étudiante' '/m/0j9vjq5' '/m/0h6hft_' [] [] []
'The Kid From Borneo' '/m/04lrdnn' '/m/04lrdnt' '/m/04lrdn5' '/m/04lrdnh' '/m/04lrdnb'
Note that when I tested this, I encoded the input CSV file as "UTF-8 without BOM" (I was using Notepad++ as editor)
Try using the following fopen command instead of the one you currently are. It specifies UTF-8 encoding for the file.
f = fopen(filename,'rt', 'UTF-8');
You can probably shorten up some of the code using this as well:
text = fscanf(f,'%c');
Lines = textscan(text,'%s','Delimiter',',');
That might help alleviate some of the pre-allocation that you're doing there.