从“stdout”格式保存的文件中读取matlab中的矩阵

时间:2014-05-21 09:16:46

标签: matlab io

我有一个打印输出大矩阵的文件,格式与打印到MATLAB控制台时的格式相同 - 即文件以

开头
dum =

 Columns 1 through 11:

   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000

并继续这样做,直到整个矩阵被打印出来。我可以用例如矩阵找出一些关于矩阵的东西。 grepwc,所以它并不完全未知,但如果没有这些工具和一些手动计算,我就没有元数据。

是否有更简洁的方法将此矩阵读入MATLAB而不是尝试使用fscan解析文件?

2 个答案:

答案 0 :(得分:0)

在浏览MATLAB中的文件读取实用程序之后,我决定不想使用它们中的任何一个,而是设计了一个小的shell脚本,它接受原始文件并以常规ASCII格式重写它我可以在MATLAB中使用load newfile加载。

完整的脚本(以下不同部分的解释):

for n in `grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'`; do  
    pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt | sed '/\s*Colu.*/d' | sed '/^$/d' > "$n.out"; 
done
paste *.out > betterdump.txt && rm *.out

好的,这是很多正则表达式。我是第一个承认它不是一个优雅的解决方案的人,但它确实有效。

What's really going on here?

第一个grep取出所有表示"列X到Y的行:"

$ grep -e 'Col' stupiddump.txt
 Columns 1 through 11:
 Columns 12 through 22:
 Columns 23 through 33:
 Columns 34 through 44:
 Columns 45 through 55:
 Columns 56 through 65:

sed中使用的下一个正则表达式会删除除每行上的最后一个数字之外的所有内容:

$ grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'
11
22
33
44
55
65

这允许我们一次只搜索其中一个集合。所以我们将这个漂亮的小脚本包装在反引号中,然后遍历结果:

$ for n in `grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'`; do
    echo "The number is $n";
  end
The number is 11
The number is 22
The number is 33
The number is 44
The number is 55
The number is 65

循环中的第一个命令选择数据文件的相关部分:

$ pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt
 Columns 1 through 11:

   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
etc...
   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000

 Columns 12 through 22:

我必须使用pcegrep才能使用多行正则表达式。我们管道的sed用任何东西替换周围的文本行,因此唯一剩下的就是实际的矩阵内容:

$ pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt | sed '/\s*Colu.*/d' | sed '/^$/d'
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
etc...
   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000

我们将此输出重定向到名为"$n.out"的文件中,以便在循环完成时,我们有一堆名为11.out22.out等的文件,其中包含相应的列集

最后,我们使用paste水平连接这些文件,并删除临时文件。在这种情况下我很幸运,并且不必担心订购,因为数字和词汇排序是相同的,但是如果你的文件的列号不具有相同的位数,那么你可能需要做一些聪明的事情。

$ paste *.out > betterdump.txt && rm *.out

现在,betterdump.txt的格式与我在第一时间输入save -ascii A键入load时的格式大致相同,因此我可以轻松阅读与{{1}}。

答案 1 :(得分:0)

您可以采取以下步骤将此类数据导入matlab,而无需过多挖掘可用功能:

  1. 从matlab内部右键单击该文件
  2. 点击导入数据
  3. 选择矩阵
  4. 设置范围A3:K6(或文件结束的位置)
  5. 点击导入,或点击生成代码
  6. 从这里你会得到这样的代码:

    filename = 'U:\MATLAB\dum.txt';
    delimiter = ' ';
    startRow = 3;
    formatSpec = '%f%f%f%f%f%f%f%f%f%f%f%[^\n\r]';
    fileID = fopen(filename,'r');
    textscan(fileID, '%[^\n\r]', startRow-1, 'ReturnOnError', false);
    dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false);
    fclose(fileID);
    dum = [dataArray{1:end-1}];
    clearvars filename delimiter startRow formatSpec fileID dataArray ans;
    

    使用此代码或使其适应以使其更方便应该不难。