Extracting number after a string in header of CSV file

43 ビュー (過去 30 日間)
Jason
Jason 2025 年 2 月 7 日 15:11
編集済み: Walter Roberson 2025 年 2 月 7 日 20:18
Hello, I have a CSV file that contains information in the headers and then numerical data.
I have no problem loading the numerical tabulated data into a uitable via readtable, but I want to pick out several strings within the header too.
I particularly want to extract the numbers in these lines
1: Memory Length,1000000,
2: Horizontal Scale,2.000E-04,
3: Sampling Period,2.000E-09,
Im nearly there but just can't quite get it:
fullpath=fullfile(folder,file)
l=readlines(fullpath);
Key = 'Memory Length';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
class(Str)
Index = strfind(Str, Key)
Str(Index(1) + length(Key):end)
line_idx =
2
Str =
"Memory Length,1000000,"
ans =
'string'
Index =
1
ans =
1×0 empty string array
Here is the typical file (also attached)
Format,1.0B,
Memory Length,1000000,
IntpDistance,0,
Trigger Address,-1,
Trigger Level,2.200E+00,
Source,CH1,
Vertical Units,V,
Horizontal Units,S,
Horizontal Scale,2.000E-04,
Sampling Period,2.000E-09,
Horizontal Old Scale,2.000E-04,
Horizontal Old Position,1.000E-03,
Firmware,V1.27.001,
Mode,Detail,
Waveform Data,
6.891787e-11,5.00e+00,
2.068918e-09,5.00e+00,
4.068918e-09,4.76e+00,
6.068918e-09,4.24e+00,
8.068918e-09,4.24e+00,
  1 件のコメント
Jason
Jason 2025 年 2 月 7 日 15:18
編集済み: Walter Roberson 2025 年 2 月 7 日 20:17
Oooh, just seen using readlines gives a string array. So can use this:
pat = digitsPattern
newStr = extract(Str,pat)
But it falls over with the E here "Horizontal Scale,2.000E-04"
l=readlines(fullpath);
Key = 'Memory Length';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
pat = digitsPattern
MemoryLength = str2double(extract(Str,pat))
Mem_Million=MemoryLength/(10^6)
Key='Horizontal Scale';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
pat = digitsPattern
H_Scale = str2double(extract(Str,pat))
Str =
"Horizontal Scale,2.000E-04,"
pat =
pattern
Matching:
digitsPattern
H_Scale =
2
0
4

サインインしてコメントする。

採用された回答

Star Strider
Star Strider 2025 年 2 月 7 日 15:59
One approach —
C1 = readcell('DummyData.txt')
C1 = 43x2 cell array
{'Format' } {'1.0B' } {'Memory Length' } {[ 1000000]} {'IntpDistance' } {[ 0]} {'Trigger Address' } {[ -1]} {'Trigger Level' } {[ 2.2000]} {'Source' } {'CH1' } {'Vertical Units' } {'V' } {'Vertical Units Div' } {[ 0]} {'Vertical Units Extend Div'} {[ 16]} {'Label' } {[<missing> ]} {'Probe Type' } {[ 0]} {'Probe Ratio' } {[ 10]} {'Vertical Scale' } {[ 1]} {'Vertical Position' } {[ -1.7600]} {'Horizontal Units' } {'S' } {'Horizontal Scale' } {[2.0000e-04]}
str = {'Memory Length','Horizontal Scale','Sampling Period'}';
idx = cellfun(@(x)strcmp(C1(:,1), x), str, 'Unif',0);
for k = 1:numel(idx)
val(k,:) = C1{idx{k},2};
end
Results = table(str, val)
Results = 3x2 table
str val ____________________ ______ {'Memory Length' } 1e+06 {'Horizontal Scale'} 0.0002 {'Sampling Period' } 2e-09
.
  4 件のコメント
Jason
Jason 2025 年 2 月 7 日 16:52
編集済み: Walter Roberson 2025 年 2 月 7 日 20:18
Is there a reason why the "table" isn't showing up in the command window?
fullpath=fullfile(folder,file)
opts = detectImportOptions(fullpath);
opts.DataLines=[1,100]; % limit the read to just the headers as 1M lines
C1 = readcell(fullpath,opts);
str = {'Memory Length','Horizontal Scale','Sampling Period'}'
idx = cellfun(@(x)strcmp(C1(:,1), x), str, 'Unif',0);
for k = 1:numel(idx)
val(k,:) = C1{idx{k},2}
end
Results = table(str, val)
fullpath =
'F:\IMAGES\ATS_IMAGES\2025\ScopeReadings\DS0030.CSV'
str =
3×1 cell array
{'Memory Length' }
{'Horizontal Scale'}
{'Sampling Period' }
val =
1000000
val =
1.0e+06 *
1.0000
0.0000
val =
1.0e+06 *
1.0000
0.0000
0.0000
Star Strider
Star Strider 2025 年 2 月 7 日 17:09
It should.
It does when I run it on my computer offline (R2024b):
Results =
3×2 table
str val
____________________ ______
{'Memory Length' } 1e+06
{'Horizontal Scale'} 0.0002
{'Sampling Period' } 2e-09
I copied that from my Command Window, and pasted it here. This should also work in R2023b, although I can’t specifically test it.
If all else fails, perhaps writetable and type would work.
.

サインインしてコメントする。

その他の回答 (1 件)

Cris LaPierre
Cris LaPierre 2025 年 2 月 7 日 16:18
There are lots of ways to do this. Here is one modified from code I shared here: https://www.mathworks.com/matlabcentral/answers/2172834-2d-matrix-resize-or-interpolation#comment_3323358
data = readData('DummyData.txt')
data = struct with fields:
Format: '1.0B' MemoryLength: 1000000 IntpDistance: 0 TriggerAddress: -1 TriggerLevel: 2.2000 Source: 'CH1' VerticalUnits: 'V' VerticalUnitsDiv: 0 VerticalUnitsExtendDiv: 16 Label: ' ' ProbeType: 0 ProbeRatio: 10 VerticalScale: 1 VerticalPosition: -1.7600 HorizontalUnits: 'S' HorizontalScale: 2.0000e-04 HorizontalPosition: 1.0000e-03 HorizontalMode: 'Main' SincETMode: 'Real Time' SamplingPeriod: 2.0000e-09 HorizontalOldScale: 2.0000e-04 HorizontalOldPosition: 1.0000e-03 Firmware: 'V1.27.001' Mode: 'Detail' Waveform: [18x2 double]
plot(data.Waveform(:,1),data.Waveform(:,2))
xlabel("Time - "+data.HorizontalUnits)
ylabel("Amplitude - "+data.VerticalUnits)
function data = readData(fname)
r=0;
data = struct;
fid = fopen(fname);
while ~feof(fid)
ln = fgetl(fid);
[param,val] = strtok(ln,",");
switch param
case 'Waveform Data'
fseek(fid,0,'eof');
fgetl(fid);
otherwise
val = strtok(val,',');
pat = asManyOfPattern(characterListPattern("0123456789-+.E"));
nums = extract(val,pat);
Param = matlab.lang.makeValidName(param);
if length(val)==length(nums{1})
data.(Param) = str2double(val);
else
data.(Param) = val;
end
end
r = r+1;
end
fclose(fid);
val = readmatrix(fname,'FileType','text','NumHeaderLines',r);
data.Waveform = val;
end
  3 件のコメント
Jason
Jason 2025 年 2 月 7 日 17:05
Could you expand on this line please
Param = matlab.lang.makeValidName(param);
Cris LaPierre
Cris LaPierre 2025 年 2 月 7 日 18:02
編集済み: Cris LaPierre 2025 年 2 月 7 日 18:02
As an example, 'Vertical Units' cannot be used as a fieldname since it is not a valid variable name. This command converts it into a valid variable name so that the parameter name can be used as the field name in the returned structure.
matlab.lang.makeValidName('Vertical Units')
ans = 'VerticalUnits'

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCharacters and Strings についてさらに検索

製品


リリース

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by