필터 지우기
필터 지우기

Extracting X Y values from a .txt file

조회 수: 10 (최근 30일)
James Andrew
James Andrew 2018년 7월 6일
댓글: dpb 2018년 7월 9일
I am working on a small project using data for a 3D printer. My problem is I am having a hard time extracting the movements of the printer to a usable array. In my text file I have things like:
;TYPE:SKIRT
G1 F1500 X18.188 Y1.255 E0.36904
G1 X18.188 Y20.575 E1.33292
G1 X26.144 Y20.575 E1.72984
G1 X26.144 Y26.455 E2.02320
;TYPE:WALL-INNER
G1 F1500 X16.988 Y2.455 E9.77394
G1 X16.988 Y21.775 E10.73782
G1 X24.944 Y21.775 E11.13474
;TYPE:WALL-OUTTER
...
The code then continues with this same format for each layer. So if there are 50 layers there are 50 wall outer sections.
If all I want is each x and y numbers for all the wall outer values (while making note of which layer the xs and ys were for) how would I do that? I have been searching the net and have found nothing for something I would think would be very simple.
  댓글 수: 6
James Andrew
James Andrew 2018년 7월 6일
This is it
James Andrew
James Andrew 2018년 7월 6일
Still trying to get the table to work but having just as much trouble.

댓글을 달려면 로그인하십시오.

답변 (2개)

Paolo
Paolo 2018년 7월 8일
편집: Paolo 2018년 7월 8일
I think the best solution in this situation is to use regular expressions. Matlab's regexp supports named capture groups, which automatically creates a structure for you, with the names of the capture groups as fields and the captured text as data. You can read more about it here.
There are three steps in the solution below.
1. Initially the text file is parsed and each layer is extracted.
2. A loop is used to iterate over every layer to extract the types.
3. A inner loop is used to iterate over every type in every layer, and X Y data is extracted.
Here's the code:
alldata = fileread('TGC.txt');
layers = regexp(alldata,'(?:LAYER:\d)(?<layer>[\w\s.;:-]*?)(?=;LAYER:|;End)','names');
n = size(layers);
for i=1:n(2)
[layers(i).types pos] = regexp(layers(i).layer,'(?:;TYPE:)(?<TYPE>[\w-]*)','names');
pos = [pos length(layers(i).layer)];
m = size(layers(i).types);
for j=1:m(2)
layers(i).types(j).data = regexp(layers(i).layer(pos(j):pos(j+1)),'(?:G1[\w\s]*X)(? <XDATA>\d*\.\d*)(?:\sY)(?<YDATA>\d*\.\d*)','names');
end
end
The output is a structure where you can easily access your data. I am attaching screenshots to clarify what the code does.
1. There are 58 layers in your code (your index starts from 0).
2. Each of your layers has several types:
3. Each type contains X and Y data:
To access your data you can use the dot notation. If you want the X and Y data for the first layer and the first type:
layer(1).types(1).data
Note that for numerical calculations you will need to convert your data from char to double.
  댓글 수: 3
Paolo
Paolo 2018년 7월 9일
Always learning :) Questions like this one are great for practicing.
Yes, I found OP's instructions slightly confusing so I figured I might as well get all of the data for him to access.
dpb
dpb 2018년 7월 9일
I've decided I'm too old a dog for that new trick...no longer the patience needed! :)

댓글을 달려면 로그인하십시오.


dpb
dpb 2018년 7월 6일
편집: dpb 2018년 7월 8일
You'll have to parse that file to locate the desired sections...none of the builtin reading tools are able to do such a file structure on their own.
fid=fopen('TGC.txt');
while ~feof(fid) % begin a loop
l=fgetl(fid); % read a line
if contains(l,';Layer count:') % found the number layers
nLay=sscanf(l,';Layer count: %d'); % read the # layers
break % now can go counted loop
end
end
XY=cell(nLay,1); % preallocate a cell arrray that size
for i=1:nLay % go until get 'em all...
l=fgetl(fid); % read record
while ~contains(l,';TYPE:WALL-OUTER'),l=fgetl(fid);end % find the desired section
g={fgetl(fid)}; % get first record in section
while ~contains(g,';') % and build cellstr array
g=[g;{fgetl(fid)}];
end
g(end)=[]; % remove the trailing header line
g(end)=strcat(g(end),{' E'}); % normalize the row delimiters
XY{i}=str2double([extractBetween(g,"X","Y") extractBetween(g,"Y","E")]);
end
fid=fclose(fid);
ADDENDUM Above seems to work with a sorta' klunky fixup...
>> james % original name for script!!! :)
>> whos XY
Name Size Bytes Class Attributes
XY 58x1 14848 cell
>> XY{1}
ans =
17.388 2.055
17.388 21.375
25.344 21.375
25.344 25.655
3.616 25.655
3.616 21.375
11.591 21.375
11.591 2.055
12.129 2.795
>>
The layer isn't saved explicitly; it's inherent in the cell index(*); it appears for this file the size of each array is the same; not sure if that were to be a requirement, hence the cell array as opposed to, say, a 3D array by layer.
(*) Of course, it's 1-based instead of 0-based since ML arrays begin (only, unfortunately) at 1.

카테고리

Help CenterFile Exchange에서 Workspace Variables and MAT-Files에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by