MATLAB Answers

How to extract specific rows & columns from a text file

52 views (last 30 days)
Farhan K
Farhan K on 25 Mar 2020
Edited: per isakson on 27 Mar 2020
I need to extract all the net names and toggle rates from a text file. total 179456 nets. Below screenshot is the few row and columns shown as example

  3 Comments

Akira Agata
Akira Agata on 25 Mar 2020
Seems that readtable function can do that. If possible, could you upload a small example of your text data?

Sign in to comment.

Accepted Answer

per isakson
per isakson on 26 Mar 2020
Edited: per isakson on 26 Mar 2020
fileID = fopen(filename);
net_names = textscan( fileID, '%s%*f%*f%f%*f', 'Headerlines',3 );
fclose(fileID);
Added later. The script
%%
filename = 'd:\m\cssm\Example.txt';
fileID = fopen(filename);
net_names = textscan( fileID, '%s%*f%*f%f%*f', 'Headerlines',4 );
fclose(fileID);
%%
net_names{1}(1:3,1)
net_names{2}(1:3,1)
outputs
ans =
3×1 cell array
{'AES/r8/t0/t3/s4/n885'}
{'AES/r3/p21[25]' }
{'AES/r7/z0[6]' }
ans =
0.0001
0.0001
0.0001

  7 Comments

Show 4 older comments
Farhan K
Farhan K on 26 Mar 2020
It works with Example.txt
But with my original file, where I have total 179456 nets, it does not work
clc
filename = 'C:\Users\kabirm\Downloads\Synthesis\switching_prob_report.txt';
fileID = fopen(filename);
net_names = textscan( fileID, '%s%*f%*f%f%*f', 'Headerlines',612);
fclose(fileID);
net_names = table( net_names{1}, net_names{2} ...
, 'VariableNames',{'Net','Togglerates'} );
disp(net_names)
Shows below error
Error using table (line 232)
All table variables must have the same number of rows.
Error in T3 (line 6)
net_names = table( net_names{1}, net_names{2} ...
per isakson
per isakson on 26 Mar 2020
"All table variables must have the same number of rows." tells me that textscan() fails to read your large file to its end. The reason is most likely that there is a line in your data file that doesn't match the format string. (I think readtable() will encounter the same problem. Might differ between releases. I run R2018b)
I reproduced your error by modifying line 44 of Example.txt to
AES/s3[124] 16.927 0.496 whats wrong
Next step is to add 'ReturnOnError' to the call of textscan()
net_names = textscan( fileID, '%s%*f%*f%f%*f' ...
, 'Headerlines',4 ...
, 'ReturnOnError', false ...
);
Now I get the error message
Error using textscan
Mismatch between file and format character vector.
Trouble reading 'Numeric' field from file (row number 40, field number 4) ==> whats wrong\n
Error in cssm (line 4)
net_names = textscan( fileID, '%s%*f%*f%f%*f' ...
which tells me that the two words, 'whats' and 'wrong', cause the error.
The cure to this error is to add 'TreatAsEmpty' to the call of textscan()
net_names = textscan( fileID, '%s%*f%*f%f%*f' ...
, 'Headerlines', 4 ...
, 'ReturnOnError', false ...
, 'TreatAsEmpty', {'whats','wrong'} ...
);
Problem solved. textscan reads the modified Example.txt without problems. The words, 'whats' and 'wrong', are converted to nan.
.
So far I've missed your attachment.
When browsing switching_prob_report.txt in the free editor notepad++ , I quickly spotted problematic lines at the end of the file. (There might be more.)
...
Trigger/n7 2.780 0.000 0.49e-7 9.772e-08
AES/*Logic0* 288.088 0.000 0.0000 0.0000 d
AES/*Logic1* 71.396 1.000 0.0000 0.0000 d
Tj_Trig 7.086 0.000 0.0000 0.0000
...
Trojan/lfsr/n25 2.489 0.000 0.0000 0.0000
--------------------------------------------------------------------------------
Total (179456 nets) 24.1493 uW
1
We can solve the problem with the extra column containing the letter 'd' by modifying the format string to skip to the end of line after the 'Togglerates' column.
%%
filename = 'd:\m\cssm\switching_prob_report.txt';
fileID = fopen(filename);
net_names = textscan( fileID, '%s%*f%*f%f%*[^\n]' ...
, 'Headerlines', 612 ...
, 'ReturnOnError', true ...
);
fclose(fileID);
reads all data lines and fails (as expected) on the three last lines.
>> net_names{1}(end-4:end)
ans =
5×1 cell array
{'Trojan/lfsr/n21' }
{'Trojan/lfsr/n24' }
{'Trojan/lfsr/n25' }
{'--------------------------------------------------------------------------------'}
{'Total' }
>> net_names{2}(end-4:end)
ans =
0
0
0
0
NaN
>>
The first column has one element more than the second. Without exactly understanding this result, I delete the elements, which originate in the footer.
%%
net_names{1}(end-1:end)= [];
net_names{2}(end) = [];
Farhan K
Farhan K on 27 Mar 2020
wow! This is why I preferred to use MATLAB rather than using Python. Excellent help

Sign in to comment.

More Answers (1)

Akira Agata
Akira Agata on 26 Mar 2020
Edited: Akira Agata on 26 Mar 2020
Thank you for uploading an example. How about the following?
% Read from text data
T = readtable('Example.txt','HeaderLines',4,'Format','%s%f%f%f%f');
T.Properties.VariableNames = {'Net','NetLoad','StaticProb','ToggleRate','SwPower'};
% Extract NetLoad and ToggleRate
T = T(:,{'Net','ToggleRate'});

  4 Comments

Show 1 older comment
Farhan K
Farhan K on 26 Mar 2020
In this file, if you go down, then you can find the Net and Toggle rate section with total 179456 nets
Akira Agata
Akira Agata on 26 Mar 2020
Thank you for attaching the data.
OK. Looking at your data, I found some irregular lines and needs to some pre-processing.
How about the following?
% Read from text data
C = readcell('switching_prob_report.txt','Delimiter','\r\n','NumHeaderLines',612);
% Delete the last 3 lines (because they don't contain data)
C(end-2:end) = [];
% Detect irregular lines (which does not end with number)
idx = ~endsWith(C,compose('%d',0:9));
% Delete characters at the end of the detected lines
C(idx) = regexprep(C(idx),'\s*[^\d]$','');
% Split the line
D = split(C);
% Extract 1st and 4th column
Net = D(:,1);
ToggleRate = str2double(D(:,4));

Sign in to comment.

Sign in to answer this question.