How to import odd and even rows from a more than one txt file ?

Hello;
I have 20 different txt files and the content of each of them is similar to the one I have stated below. I need to save the numbers in the odd rows of the 1st column as 'A' and the numbers in the even rows of the 3rd column as 'B'; but after the 150th row, the text part starts and I should not include this part.
Can you help me?
Thank you
txt file:
x y z
1 2 3
4 5
6 7 8
9 10
.
.
.
.
The explanation part starts after line 150th row.

 Accepted Answer

hello
maybe this ?
I wasn't sure when you say even / odd rows if we take the first line (x y z) into account or not
so choose your option in the code
clc
clearvars
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'data*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B] = do_the_job(fileDir,filename,start_line,stop_line)
D=readlines(fullfile(fileDir,filename)); % read as string array
D= D(start_line:stop_line,:);
% remove empty string
D(D == '') = [];
D = str2double(split(D,' '));
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
end

16 Comments

First of all thank you very much for the reply.
Just importing the numbers will be enough for me. I don't need to take the first line and I encountered with this error:
Error using split
Element 2 of the text contains 12 delimiters while the previous elements have 21. All elements must contain the same number of delimiters.
hello again
do you have a data file to share which triggered the issue ?
The attached file is one of them
try this
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B] = do_the_job(fileDir,filename,start_line,stop_line)
D=readmatrix(fullfile(fileDir, filename),"NumHeaderLines",start_line-1);
D= D(1:stop_line,:);
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
end
Hello again;
I also need 2 values (i.e. I need 4 different values in total, odd and even rows in column 1, even rows in column 2 and even values in column 3) so I edited the code as follows; but I couldn't see these two other values in workspace. I'll be happy if you can help me.
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B] = do_the_job(fileDir,filename,start_line,stop_line)
D=readmatrix(fullfile(fileDir, filename),"NumHeaderLines",start_line-1);
D= D(1:stop_line,:);
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
C = D((1:2:m),1);
E = D((2:2:m),2);
end
hello again
you forgot to add the new variables in the output of the function
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B] = do_the_job(fileDir,filename,start_line,stop_line)
end
must be
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B,C,E] = do_the_job(fileDir,filename,start_line,stop_line)
end
Hello again;
I changed it like this but it didn't generate the C and E values in the workspace
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B,C,E] = do_the_job(fileDir,filename,start_line,stop_line)
D=readmatrix(fullfile(fileDir, filename),"NumHeaderLines",start_line-1);
D= D(1:stop_line,:);
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
C = D((1:2:m),1);
E = D((2:2:m),2);
end
this is funny
maybe my eyes are too old but it seems we have the same code , and when I test it with your FX.txt file , I got the variables as expected in my workspace :
>> whos
Name Size Bytes Class Attributes
A 75x1 600 double
B 75x1 600 double
C 75x1 600 double
E 75x1 600 double
S 1x1 1133 struct
fileDir 1x27 54 char
k 1x1 8 double
start_line 1x1 8 double
stop_line 1x1 8 double
code
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B,C,E] = do_the_job(fileDir,filename,start_line,stop_line)
D=readmatrix(fullfile(fileDir, filename),"NumHeaderLines",start_line-1);
D= D(1:stop_line,:);
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
C = D((1:2:m),1);
E = D((2:2:m),2);
end
The old eyes are mine, not yours. It definitely works that way, I made a little mistake. Thank you very much for your help.
sorry to bother you again. I want to save the a and b values we received one by one (as A.a1.a /A.a2.a...) however, when I looked inside all of them, I saw that only the data in the last file was received. Where am I going wrong? Can you help me?
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line)
end
for kk=1:150
b=reshape(B(:,1),[5,30])';
fie1=sprintf('b%d',kk);
B.(fie1).b=b;
a=(reshape(A(:,1),[5,30])');
fie2=sprintf('a%d',kk);
A.(fie2).a=a;
end
save('A.mat','A');
save('B.mat','B');
%%%%%%%%%%%% function %%%%%%%%%%%%%%%
function [A,B,C,E] = do_the_job(fileDir,filename,start_line,stop_line)
D=readmatrix(fullfile(fileDir, filename),"NumHeaderLines",start_line-1);
D= D(1:stop_line,:);
[m,n] = size(D);
% I need to save the numbers in the odd rows of the 1st column as 'A'
% and the numbers in the even rows of the 3rd column as 'B';
% % option 1 : "odd / even" rows without taking the first line (headerline)
% % in account
% A = D((1:2:m),1); % odd rows of the 1st column as 'A'
% B = D((2:2:m),3); % even rows of the 3rd column as 'B';
% option 2 : "odd / even" rows with taking the first line (headerline)
% in account
A = D((2:2:m),1); % odd rows of the 1st column as 'A'
B = D((1:2:m),3); % even rows of the 3rd column as 'B';
C = D((1:2:m),1);
E = D((2:2:m),2);
end
hello
no problem
can you zip couple of txt (data) files so I can test the loop
Thank you very much for your feedback, the zip file is attached.
hello again
the code works if you don't use the same letter A and B once for the numerical arrays (first for loop) and then after for a structure (second for loop)
so the structure names are now AS and BS to avoid this mix up
next, i don't now why but on your side it seems A and B have length = 150 , but with the provided txt files , it comes on my side with length = 75
so I had to make some mods in the second for loop , but you can easily switch back to your own version :
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line);
% size(A)
% size(B)
end
for kk=1:75
b=reshape(B(:,1),[5,15])';
fie1=sprintf('b%d',kk);
BS.(fie1).b=b;
a=(reshape(A(:,1),[5,15])');
fie2=sprintf('a%d',kk);
AS.(fie2).a=a;
end
Hello again;
I think I explained the problem wrong.I am sorry for this. I want to do it like this;
In total, for example, in my 3rd column, there are 75 data in each of the 4 files. For example, when I enter ''Bs'' from workspace, I want to have 4 files as b1, b2, b3 and b4. (in b1 the values in the 3rd column of the 75 numbers in the 1st file, the 75 values in the 3rd column in the 2nd file in b2, the 75 values in the 3rd column in the 3rd file in b3, the 75 values in the 3rd column in the 4th file in b4). For ''As'' it will be for the numbers in the even rows in the 1st column of the files. My code worked when I corrected the letter complexity you mentioned, but it wrote the values in the 4th file into all of these files.
Isn't it this way you wanted the structures be organized ?
fileDir = pwd; % choose your working directory
start_line = 2;
stop_line = 150;
S = dir(fullfile(fileDir,'F*.txt')); % get list of data files in directory
S = natsortfiles(S); % sort file names into natural order , see :
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
for k = 1:length(S)
[A,B,C,E] = do_the_job(fileDir, S(k).name,start_line,stop_line);
% size(A)
% size(B)
fie1=sprintf('b%d',k);
BS.(fie1) = B;
fie2=sprintf('a%d',k);
AS.(fie2) = A;
end
you don't need a second for loop, everything is done in the first loop
now AS is
AS = struct with fields:
a1: [75×1 double] filled with A array of first FX file
a2: [75×1 double] filled with A array of second FX file
a3: [75×1 double] filled with A array of third FX file
a4: [75×1 double] filled with A array of fourth FX file
same logic for BS :
BS = struct with fields:
b1: [75×1 double] filled with B array of first FX file
b2: [75×1 double] filled with B array of second FX file
b3: [75×1 double] filled with B array of third FX file
b4: [75×1 double] filled with B array of fourth FX file

Sign in to comment.

More Answers (1)

try this:
textfiles = dir('*.txt');
numfiles = length(textfiles);
mydata = cell(1, numfiles);
for k = 1:numfiles
mydata{k} = readmatrix(textfiles(k).name);
end
a=[mydata{:}];
maindata=a(1:149,:);
idx=1;
b=[maindata(:,idx:idx+2); maindata(:,idx+3:idx+5); maindata(:,idx+6:idx+8)];
% odd rows of the 1st column as 'A'
A=b(1:2:end,1);
% the numbers in the even rows of the 3rd column as 'B'
B=b(2:2:end,3);

Asked:

on 6 Dec 2022

Commented:

on 14 Dec 2022

Community Treasure Hunt

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

Start Hunting!