我写了一个脚本,可以帮助我在Matlab中手动导入测试期间记录的数据。可以避免`eval()`吗? (在运行时分配变量名称)
每个测试运行都会在.csv
文件中保存约2600个变量,每个文件有2个标题行,两列数据和;
是分隔符。
的文件名来从监视程序使用的内部C-结构,且这种这样的:foo.bar.another.foo.bar.local_varname#VALUE.csv
,我想用这个Matlab中重新创建的结构,以只保存在test_name.mat
文件。
很多时候,local_varname
的长度超过63个字符,所以我有一些替换规则为了缩短名称而没有使用Matlab截断名称(所以试图避免命名冲突)。
这是代码
clear all
clc
% Main names
path_self = pwd;
backslash_indices = strfind(path_self,'\');
test_name = path_self(backslash_indices(end)+1:end); % the directory name gives me the test_name
% Preallocation
filenames = cell(1,2600);
addresses = cell(1,2600);
i=0;
% Full list
MyFiles = dir(path_self);
% Discard subdirectories and non interesting files
for k=1:length(MyFiles)
if ~MyFiles(k).isdir,
if ~isempty(strfind(MyFiles(k).name,'#VALUE.csv'))
i=i+1;
% Too many files
if i > length(filenames)
filenames = [filenames cell(1,100)];
addresses = [addresses cell(1,100)];
end
% Naming Substitution Rules
%%% INSERT HERE BUNCH OF RULES
% Addresses and names
filenames{i} = strrep(filename,'#VALUE.csv','');
addresses{i} = fullfile(path_self, MyFiles(k).name);
end
end
end
filenames = filenames(1:i);
addresses = addresses(1:i);
% Check that no conflicts are created
if length(filenames) ~= length(unique(filenames))
error('filenames not unique')
end
% Housekeeping #1
clear MyFiles backslash_indices i k path_self
% Import data
for j=1:length(filenames)
% Read data
Data = importdata(addresses{j}, ';', 2);
% Assign data
eval([filenames{j}, '.time = Data.data(:,1)./1000000;']); % Converted in seconds
eval([filenames{j}, '.values = Data.data(:,2);']);
% Let's avoid data corruption
clear Data
end
% Housekeeping #2
clear filenames addresses j
% Save data struct
save(test_name, '-regexp', '^((?!name).)*$')
现在我的问题 虽然研究信息,并帮助写上面的代码我经常发现人们皱着眉头在使用eval()
:为什么会这样呢?在上述情况下,我能避免吗?
由于
EDIT 如所建议的通过@wakjah,我测试了containers.Map()
方法。不幸的是不适合我们的需要,因为那时需要一个密钥列表,并且访问数据不是很友好(记住我有〜2600个变量,意味着至少有相同数量的密钥)
至于@Dennis Jaheruddin提出的要求是,数据结构是可用的并且不会产生任何类型的冲突,即使使用这些长的varnames(假设两个连续的.
之间的每个名称*小于63个字符长)
*我很抱歉没有使用更好的技术术语
不幸的是,这个解决方案创建了一个不同的问题:63个字符的限制被强加在完整的'filenames {j}'上(在某些情况下达到180个字符),而'eval()'我必须只关心'local_varname'。另外,如果'filenames {j}'包含一个'.'(对我来说总是如此),它会返回一个错误 – Federico
如何避免使用'eval'?我只是试了一下 - 当你的字段名长于63个字符时,MATLAB会发出警告,不管你是否使用'eval'。也许我误解了你......无论如何,如果你确实需要长时间的域名,你是否考虑过使用['containers.Map'](http://www.mathworks.co.uk/help/matlab/map- containers.html)? – wakjah
实施例:'文件名{1} = ABCDE.ABC0.ABCDE.ABC_AA_AA_AAA_00.BBB_BBB_00_BBB_CCCC_ABCDE_ABCDEFGHIJKLMNO_AAAA0.A_ABCDE_CCC_DDDD_EEEEE_AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD00_DDDD0'(153字符长) 随着'的eval()',如果我收缩的最后部分(现在71炭长)至小于63字符,我没有问题,与你的代码1)我有一个错误的'.'s和2)它抱怨'文件名{1}'太长 – Federico