我寫了一個腳本,可以幫助我在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