【问题标题】:How do I write a text file in the same format that it is read in MATLAB?如何以与在 MATLAB 中读取的格式相同的格式编写文本文件?
【发布时间】:2009-12-15 03:52:25
【问题描述】:

我过去曾问过related question,感谢这里专家的帮助,我知道如何阅读该文件。现在我有一个新问题。我首先像这样从文件中读取数据:

fid = fopen('D:\file.txt', 'rt');
a = textscan(fid, '%s %f %f %f %f %f %f', ...
             'Delimiter',',', 'CollectOutput',1, 'HeaderLines',1);
fclose(fid);

然后我处理文件并更改列的一些值。现在我想用新值以与我的file.txt 完全相同的格式编写一个新文件newfile.txt。我该怎么做?

如果我执行以下操作:

M = [datenum(a{1}) a{2}];
dlmwrite('newfile1.txt', M);

它给了我一个新文件,没有我的第一行标题,也没有我想要的格式的第 1 列和第 2 列。

我的文件格式如下:

date        time,   M01, M02, M03, M04, M05, M06
8/15/2009, 0:00:00, 5.8, 7.8, 7.8, 7.3, 0, 7.9
8/15/2009, 0:10:00, 7.1, 8.1, 8.1, 7.7, 0, 8.1
8/15/2009, 0:20:00, 6.8, 7.4, 7.6, 7.1, 0, 7.3
8/15/2009, 0:30:00, 5.6, 6.8, 7.1, 6.6, 0, 6.8
8/15/2009, 0:40:00, 3.9, 6.2, 6.4, 6.2, 0, 6.4
8/15/2009, 0:50:00, 4.6, 5.5, 6.1, 5.8, 0, 5.6
8/15/2009, 1:40:00, 7, 7, 7.2, 6.9, 0, 6.3

我可以制作一个新的 file.txt 格式

我的文件格式如下:

                5.8, 7.8, 7.8, 7.3, 0, 7.9
                7.1, 8.1, 8.1, 7.7, 0, 8.1
                6.8, 7.4, 7.6, 7.1, 0, 7.3
                5.6, 6.8, 7.1, 6.6, 0, 6.8
                3.9, 6.2, 6.4, 6.2, 0, 6.4
                4.6, 5.5, 6.1, 5.8, 0, 5.6
                7, 7, 7.2, 6.9, 0, 6.3

有人可以帮我将标题和前 2 列复制到这个新文件中吗?

【问题讨论】:

  • 有什么想法吗?我试过覆盖,但它不起作用
  • @AP:我编辑了您的问题以修复数据文件的格式。看来您在日期和时间之间有一个额外的,,而您之前的问题中没有(这导致您读取文件的代码失败)。
  • @gnoice:不,我确实有,我每天都以不同格式获取文件,我阅读的最简单方法是 data=dlmread('D:\file.txt,',',1,2) ;并由 dlmwrite ('newfile.txt',data,',',1,2);
  • @gnoice : fid = fopen('d:\file.txt,'r');头=fgetl(fid);这给了我标题我不知道 2 如何获得 1,2 列以及如何在我的 newfile.txt 中添加此标题
  • @AP:您在问题顶部用于读取数据文件的代码不适用于您作为示例提供的文件格式。

标签: matlab file-io text-files


【解决方案1】:

注意:我已更新答案以使用问题中指定的最新文件格式(即日期和时间值之间的逗号)。我还编写了下面的代码来处理列数已知但行数可变的非常大的文件。

首先,您必须使用以下更新的代码读取文件(使用函数FGETS 保存顶行):

fid = fopen('D:\file.txt','rt');  %# Open the file
topLine = fgets(fid);             %# Read the top line and store it in a string
data = textscan(fid,'%f','Delimiter',',/:');  %# Read the data
fclose(fid);                      %# Close the file

接下来,您必须使用已知的数据列数重塑data(不计算日期和时间列):

N = 74;  %# Number of columns of data after the date and time
data = reshape(data{1},N+6,[])';

现在data 是一个矩阵,其中前六列包含日期和时间信息(月、日、年、小时、分钟和秒),所有其他数据位于剩余的N 列中。如果您需要对日期和时间值进行任何操作,可以查看以下函数以了解如何将它们转换为不同的格式:DATENUM、DATESTR 和 DATEVEC。

修改data 中的值后,您可以使用for 循环和FPRINTF 函数重新保存它:

fid = fopen('newfile1.txt','wt');  %# Open the file
fprintf(fid,'%s',topLine);         %# Print the top line
for i = 1:size(data,1)             %# Loop over the rows of data
  fprintf(fid,'%d/%d/%d, %d:%d:%d',data(i,1:6));  %# Print the date
  fprintf(fid,', %.1f',data(i,7:end));            %# Print the data
  fprintf(fid,'\n');                              %# Print a newline
end
fclose(fid);                       %# Close the file

我用data 的 86400×80 矩阵运行上述代码,将数据写入文件大约需要 30 秒。

【讨论】:

  • @Gnoice:谢谢,但无论如何让它更快?我需要 5 分钟来运行每个文件,如果我用我的 cmets 跳过 2 列和标题(我在上面写过),它只需要 10 秒。我有 50 个文件要运行和处理!!
  • @AP:我添加了我认为应该更快的答案的新版本。
  • @Gnoice :我改回了您在日期和时间之间删除 , 的一个编辑,因为我的文件用逗号分隔它们。所以我在第 1 列中有日期,在第 2 列中有时间。
  • @gnoice : 两个问题 1) 评估 'char (10.*ones(size(M,1),1))' 的内存不足 2) davevec 失败并且读取的日期过多领域。错误看起来像“2009 年 10 月 5 日 00:00:00 1 1 8 5 ... 中的日期字段太多”
  • @AP: 1) 如果内存不足,则意味着您的矩阵 M 必须太大,以至于 MATLAB 没有足够的空间来创建 data。您可以尝试通过将data = [... 替换为M = [... 来覆盖M。 2)您应该使用函数 DATESTR(如我上面的代码),而不是 DATEVEC。
【解决方案2】:

dlmwrite 将一个变量(例如,您的 M 数组)写入 ASCII 文本文件,如您所知。查看该函数的文档以了解如何设置分隔符(在每行中的值之间获取 , )以及如何附加到现有文件。

要编写标题行,我建议您设置一个字符串数组,填充它并使用 dlmwrite 将其写入输出文件。

现在,如果您想写入文件的其余部分(M 数组加上 2 个日期/时间的前导列),您将需要创建一个大小与 M 相同的临时数组加上 2 个额外的列。由于您的数据值是浮点数,而您的日期和时间是某种结构化数据(也许是字符串),我认为 Mtemp 必须是一个字符串数组。创建它后,您可以使用单个 dlmwrite 语句将其附加到输出文件中。

请注意,num2str 的运行方式与您对向量的希望一样,但我不确定它是否可以被强制放入 , 值之间。但是,它可以以您指定的格式写入数字。

如果这不能为您提供所需的输出,或者您的数组太大而无法复制和扩展,或者您有其他原因不喜欢建议的解决方案,那么我担心您将不得不编写一个循环来一次写一行输出,并使用低级文件写入函数。

问候

标记

【讨论】:

    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    相关资源
    最近更新 更多