MATLAB Answers

I want to read a text file having strings and numeric data. Is there any better function than textscan?

259 views (last 30 days)
Hamza
Hamza on 8 Sep 2012
Answered: Sarah Palfreyman on 30 Apr 2018
Dear Users,
below are the few lines of the text which I want to display individually. It is the data of a TLE (Two-Line elements)
I want to separately read each data from the TLE. How can I do that? I want to skip the first 5 lines and start reading the data from 6th row till the end. I will be thankful if anyone can help.
=====================================================================
24652 1996-063A ARABSAT-2B
Launched: 1996-11-13 (318) Start Date: 1996-06-12 (164)
Decayed: Stop Date: 2003-12-20 (354)
=====================================================================
1 24652U 96063A 96318.74847837 -.00000020 00000-0 00000+0 0 14
2 24652 3.9929 210.6007 7281127 177.7757 190.4436 2.27277888 06
1 24652U 96063A 96319.62211352 -.00000020 00000-0 00000+0 0 31
2 24652 3.9929 210.3183 7284735 178.4392 185.2995 2.27373269 12
1 24652U 96063A 96319.62351606 .00008082 00000-0 30835-2 0 24
2 24652 3.9764 210.1654 7280836 178.5436 186.6267 2.27380102 20
1 24652U 96063A 96319.62356237 .00009638 00000-0 38025-2 0 37
2 24652 3.9632 210.3512 7280110 178.4006 186.6625 2.27374993 25
1 24652U 96063A 96320.05952563 -.00002597 00000-0 -98092-3 0 63
2 24652 3.9623 210.1661 7275699 178.7092 185.6294 2.27896863 39
end
  3 Comments
Oleg Komarov
Oleg Komarov on 8 Sep 2012
@Srikanta: dlmread() is a wrapper of textscan. Also it will not allow me to directly import the lines identified with 2 (first col) as doubles but I will have to convert.
I usually prefer to have more control on the importing procedure and try to avoid datatype conversions.

Sign in to comment.

Accepted Answer

Oleg Komarov
Oleg Komarov on 8 Sep 2012
Using textscan you can import one line and skip the next one (I save your example to test.txt).
% Import lines which start with 1
fid = fopen('test.txt');
line1 = textscan(fid, '%f%s%s%f%f%s%s%f%f\r\n %*[^\n]','HeaderLines',5);
fclose(fid);
% Import lines which start with 2
fid = fopen('test.txt');
line2 = textscan(fid, '%f%f%f%f%f%f%f%f%f\r\n %*[^\n]','HeaderLines',6);
fclose(fid);
The format specifier, e.g. for line 2, is '%f%f%f%f%f%f%f%f%f\r\n %*[^\n]'. Note that I read in all the values of the line, then I proceed to next line with \r\n, and I skip its content with %*[^\n]. This way I read every each line.
  6 Comments
Oleg Komarov
Oleg Komarov on 10 Sep 2012
I only gave an example for the first two columns, but you have to code all the remaining within [...].
If the column is double, then num2cell... Otherwise simply line1{:,n}.
if tou have problems extending my example post here the syntax which is not working.

Sign in to comment.

More Answers (5)

José-Luis
José-Luis on 8 Sep 2012
Edited: José-Luis on 8 Sep 2012
This could work:
fid = fopen('bla.txt','r');
%Advance five lines:
linesToSkip = 5;
for ii = 1:linesToSkip-1
fgetl(fid);
end
%Process all remaining lines
tline = fgetl(fid);
your_data = []; %You should allocate if you know how large your data is
while (~isempty(tline) )
tline = fgetl(fid);
%Getting rid of non-numbers
tline = regexprep(tline,'[^0-9\s+-.eE]','');
your_data = [your_data; str2num(tline)];
end
fclose(fid);
Note that 30835-2 is interpreted as 30833. If you want them separated then you should modify the regular expression, but then you cannot not build your_results in the same manner (some rows would have nine values, the others more). What i tried to do is to get a numeric array from your data, but you can get a cell array as well.
Maybe that is more what you want, for each tline you can get a cell array:

Javier
Javier on 8 Sep 2012
Edited: Oleg Komarov on 8 Sep 2012
Hello Hamza
The first column is a dummy variable (1,2) and as Oleg says the column count in 1 and 2 are different. Next, I define the steps to get the data. Solution done in Matlab R2012a for Mac.
Step 1 Load or import file
Data=importdata('test.rtf'); %Is how text edit save data in Mac
When you do this, the data that you want to get start at row 13.
Step 2 Get the data
Case 1 Dummy value is 1
[Col1] = textscan(Data{13,1}, '%d %s %s %f %f %f %d %d %d %d %d');
For the first row data you get:
Col1=[1 '24652U' '96063A' 96318,7484783700 -2,00000000000000e-07 0 0 0 0 0 14]
Case 2 Dummy value is 2
[Col2] = textscan(Data{14,1}, '%d %s %s %f %f %f %f %f %d');
Col2 =[2 '24652' '3.9929' 210,60070 7281127 177,77570 190,44360 2,27277880 6]
If this or previous answers solve your question, please grade.
Best regards
Javier
  3 Comments

Sign in to comment.


Tom
Tom on 8 Sep 2012
What format do you want the data in? Using importdata gives you all the data as strings- you can convert the numeric data and split up the data into rows 1 and 2 easily.
%import data from txt file (using space as delimiter)
L=importdata('TLEtest.txt',' ');
%get data, ignoring first 5 lines
Data=L.textdata(6:end,:);
  7 Comments

Sign in to comment.


Tom
Tom on 9 Sep 2012
This is quite scrappy but it gives you the data quite clearly in a cell array:
n=5; %lines to skip
A=fileread('TLETest.txt');
L=[1 regexp(A,'\n') length(A)+1]';
nLines=length(L)-n-1;
T=cell(nLines,1);
%break string of characters into rows and columns
Data=cell(nLines,9);
for ii=1:nLines
T=A(L(n+ii):L(n+ii+1)-1);
B=regexp(T,'\s*','Split');
B(cellfun('isempty',B))=[];
Data(ii,:)=B;
end
  19 Comments

Sign in to comment.


Community Treasure Hunt

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

Start Hunting!