I want to read a text file having strings and numeric data. Is there any better function than textscan?
Mostra commenti meno recenti
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 Commenti
Oleg Komarov
il 8 Set 2012
Better than textscan. I really doubt that and I think you meant "easier".
Srikanta Sharma
il 8 Set 2012
Hi Oleg,
if your data is saved as a .txt format, then I would use the following code:
Data=dlmread('/Users/oleg/Desktop/....txt'); in order to read the .txt from line 5, Data =Data(5:end,:);
Oleg Komarov
il 8 Set 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.
Risposta accettata
Più risposte (5)
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:
1 Commento
Hamza
il 9 Set 2012
Javier
il 8 Set 2012
Modificato: Oleg Komarov
il 8 Set 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 Commenti
Oleg Komarov
il 8 Set 2012
On Col1 you lose information on the sign, e.g. 3rd line starting with 1 value '30835-2'.
Javier
il 9 Set 2012
Hi Oleg.
As I understand, there is no number 30835-2. What you could have is 30835e-2 or just two numbers 30835 and -2 (this is what I program in Matlab 2012a and it works just fine). If you work with the expression '30835-2', Matlab will interpret as a minus operation and the result will be 30833.
Oleg Komarov
il 9 Set 2012
Please, disregard my comment above.
Tom
il 8 Set 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 Commenti
Oleg Komarov
il 8 Set 2012
Undoubtedly the syntactically clearest and simplest approach (although not the most efficient).
Hamza
il 9 Set 2012
Oleg Komarov
il 9 Set 2012
Because he imports everything and then it's up to you to separate it or keep together.
Hamza
il 9 Set 2012
I guess the answer to your question is: no. Importdata is simple. It is not flexible. It seems to me you have two options:
- If you generate the data yourself, modify your algorithm so it produces something that is more amenable to importdata.
- Use some of the other suggestions presented here.
When you have that mix of characters and numbers, there is no one-liner that will provide a foolproof solution, you will always need to massage it. To make matters worse, it is not regular data, as it changes from line to line.
Hamza
il 9 Set 2012
Oleg Komarov
il 9 Set 2012
You have to pass the 'filename' of the file you like to import, i.e. uiimport creates a function.
Tom
il 9 Set 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 Commenti
Hamza
il 9 Set 2012
Tom
il 9 Set 2012
I don't get that error, it might be the way the text file is formatted? Have you added anything to the code? That line is only line 12 for me.
Tom
il 9 Set 2012
You could scratch all that nonsense and try this instead:
fid=fopen('TLEtest.txt');
A=textscan(fid,'%s','HeaderLines',5);
Data=reshape(A{1},9,[])';
fclose(fid);
Hamza
il 9 Set 2012
Tom
il 9 Set 2012
To test it I used the data you posted originally, copied and pasted into a text file- is this similar to what you are using?
Hamza
il 9 Set 2012
Tom
il 9 Set 2012
Is there anything written at the bottom of the file after all the data?
Tom
il 9 Set 2012
If that's there is, then this line should work instead:
Data=reshape(A{1}(1:end-3,:),9,[])';
Hamza
il 9 Set 2012
Hamza
il 10 Set 2012
Do you mean like this?
Line1=Data(1:2:end,:);
Line2=Data(2:2:end,:);
Hamza
il 10 Set 2012
Hamza
il 10 Set 2012
Tom
il 10 Set 2012
How do you want to store it? Each as a separate variable? e.g.
a=9;
b=6;
...
f='A';
Hamza
il 10 Set 2012
Tom
il 11 Set 2012
There are probably many ways you can do it, I'd ask this as a seperate question so more people can see it.
Hamza
il 11 Set 2012
Hamza
il 12 Set 2012
Sarah Palfreyman
il 30 Apr 2018
0 voti
Categorie
Scopri di più su Data Type Conversion in Centro assistenza e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!