使用 textscan 将 ASC 文件读入 MATLAB - 可变列长度

Read ASC file into MATLAB using textscan - variable column lengths

我正在尝试将以下数据读入 MATLAB:

'0.000000 1  18EFFA59x  Rx D 8  AD  09  02  00  00  00  00  30'  
'0.004245 1  14EFF01Cx  Rx D 6  DB  00  FF  FF  00  71'  
'0.004640 1  CEF801Cx   Rx D 3  3F  00  3B'  
'0.005130 1  14EF131Cx  Rx D 6  DB  00  FF  FF  00  71'  
'0.005630 1  CEF801Cx   Rx D 3  3F  00  C3'  
'0.010015 1  18EFFA59x  Rx D 8  AD  07  01  00  00  00  00  30'  
'0.014145 1  CF004F0x   Rx D 8  F0  FF  7D  00  00  FF  FF  FF'  
'0.015060 1  18EFFA59x  Rx D 8  AD  07  02  00  00  00  00  30'  
'0.018235 1  18EF1CF0x  Rx D 8  F2  1E  05  FF  FF  00  71  FF'  
'0.018845 1  18EA5941x  Rx D 3  09  FF  00'  

我可以轻松地将每一行作为字符串读取 - 但为了使 post 处理更有效率,我想用分隔符分隔每一行 - 这是空白。换句话说,最终结果应该是一个非单例元胞数组。我似乎找不到一种非常有效的方法来做到这一点。效率很重要,因为这些文件有几百万行长,并且在 MATLAB 中使用 strings/cells 处理需要很长时间。

如有任何帮助,我们将不胜感激。谢谢

你似乎有固定宽度的字段,所以我会这样对待它,让 textscan 通过关闭定界符和空格并定义字段宽度和明确类型:

test = {...
    '0.000000 1  18EFFA59x  Rx D 8  AD  09  02  00  00  00  00  30'
    '0.004245 1  14EFF01Cx  Rx D 6  DB  00  FF  FF  00  71'
    '0.004640 1  CEF801Cx   Rx D 3  3F  00  3B'
    '0.005130 1  14EF131Cx  Rx D 6  DB  00  FF  FF  00  71'
    '0.005630 1  CEF801Cx   Rx D 3  3F  00  C3'
    '0.010015 1  18EFFA59x  Rx D 8  AD  07  01  00  00  00  00  30'
    '0.014145 1  CF004F0x   Rx D 8  F0  FF  7D  00  00  FF  FF  FF'
    '0.015060 1  18EFFA59x  Rx D 8  AD  07  02  00  00  00  00  30'
    '0.018235 1  18EF1CF0x  Rx D 8  F2  1E  05  FF  FF  00  71  FF'
    '0.018845 1  18EA5941x  Rx D 3  09  FF  00'};

test = strjoin(test', '\n');

C = textscan(test, '%8.6f %2u %11s %4s %2s %2u %33s', 'delimiter', '','whitespace','');

col1 = C{1};
col2 = C{2};
col3 = strtrim(C{3});
col3 = cellfun(@(x)hex2dec(x(1:end-1)), col3); % for instance.
col4 = strtrim(C{4});
col5 = strtrim(C{5});
col6 = C{6};
col7 = strtrim(C{7});

在现实世界中,您会用文本字符串替换文件 ID。对于最后一个可变长度字段,只需读入整个内容,确保指定最大可能长度。 MATLAB 将读取一个字段,直到它到达末尾或到达换行符(事实上,我将最后一个字段的宽度增大了 1,只是为了确保)。然后将每个字段聚合到一个单元格中。我还冒昧地将第三个字段从十六进制转换为十进制,以显示您可以如何 post 进一步处理数字。

进一步说明,如果您确实有巨大的文件并且需要最大速度,您可以通过指定 %*ns 跳过字符字段上的 strtrim 步骤,其中 n 是所需的字段宽度,对于任何已知的间隙,例如第 3 列和第 4 列之间的 2 个字符的间隙。星号表示忽略该字段。然而,我发现这种处理方式更具可读性和直观性,并且在其中一个字段(例如第 4 个)偶尔有 3 个字符的条目的情况下会留下很小的误差。