2014-11-24 74 views
1

说我有一个目录的完整文件名如重合:MATLAB:只挑文件名与一些输入字符串

1242349_blabla.wav 
fdp23424_asdf.wav 
o2349_0.wav 

,我对每一个新行与这些文件名中的数字相吻合的输入文本文件中列出的唯一ID (例如上面第二个文件名的'23424')。

我想构建只包含在该目录下,以输入文本文件中的一些ID一致的文件名文件名的结构:

fid = fopen('input.txt'); 
input = textscan(fid, '%s', 'Delimiter', '\n'); 

filenames = dir(fullfile('/somedir/', '*.wav')); 

for i = 1:length(filenames) 
    for j = 1:length(input) 
     if (strfind(input{1}(j), filenames(i).name)) ~= []) 
      % create new struct with chosen filenames 
     end 
    end 
end 

但是,我得到的错误“未定义功能“NE '用于输入'cell'类型的输入参数。我尝试了大量的选择无济于事。此外,输入评估为38x1单元格,但其长度为1,因此内部循环只会去一次......任何想法?

+3

你应该总是在MATLAB中使用'isempty'而不是'== []'。 – MrAzzaman 2014-11-24 21:25:15

回答

1

正则表达式绝对是最灵活和最强大的解决方案。但是,如果您的需求更简单......您可以使用更简单的方法逃脱,比如在dir命令中使用通配符。试试这样:

%get your file IDs from the input file 
fid = fopen('input.txt'); 
input = textscan(fid, '%s', 'Delimiter', '\n'); 
IDs = input{1}; 

%loop over each string 
myfilenames = {}; 
for idx = 1:length(IDs) 
    %get all files build off the given ID 
    fnames = dir(['somedir/*' IDs{idx} '*.wav']); %wildcards! 

    %gather the new filenames that match 
    for Ifname=1:length(fnames) 
     myfilenames{end+1}=fnames(Ifname).name; 
    end 
end 
1

我会用regular expressions来搜索单元格数组中ID的出现。正则表达式旨在为您搜索特定字符串中的模式。因为你想在一组字符串中搜索特定的数字,所以我肯定会推荐你使用它。具体而言,使用regexp函数,并且要搜索的模式是您想要搜索的ID。

如何工作,您可以提供一个字符串的单元格数组,并且输出将是另一个单元格数组,其中每个元素都是一个数字数组,它决定了您要查找的特定模式的起始索引单元格数组中的特定字符串。如果数组是空的,这意味着我们没有找到任何符合您要求的模式。如果它不是空的,那么它将包含ID在字符串中的起始索引。这并不重要 - 你想要确定ID是否存在于特定的字符串中,因此检查每个数组是否为空是有用的。

因此,考虑到您通过dir读取的文件名,我们可以创建一个存储文件名的单元阵列,运行regexp,然后过滤掉那些不包含所需ID的文件名。类似这样的:

f = dir(fullfile('/somedir/', '*.wav')); 
filenames = {f.name}; 
ID = 23424; 
check = regexp(filenames, num2str(ID)); 
filtered_ind = cellfun(@isempty, check); 
final_files = f(~filtered_ind); 

第一行代码从您所需的目录中读取文件。第二行代码从结构的每个name字段中提取名称作为单元阵列。第三行是你想检查的ID。第四行对文件名进行regexp调用,并搜索包含所需编号的文件名。请注意,我们需要将数字转换为字符串,因为该模式预期为字符串。之后的下一行发现那些做文件名不有你正在寻找的ID,和最后一行就是找那些有你要找的ID文件。

然后,您可以继续前进,开始你的处理。具体地说,可以遍历该单元阵列,并继续创建您的结构每个元素在该单元格:

for i = 1:length(final_files) 
    s = final_files(i); %// Get the dir structure for a file that passed the ID check 

    %// Create your structure now... 
    %// ... 
end 

然而,你必须要检查身份证的系列。我们可以简单地把上面的代码并申请一个循环了。换句话说,你会做这样的事情:

fid = fopen('input.txt'); 
input = textscan(fid, '%s', 'Delimiter', '\n'); 
IDs = input{1}; 

f = dir(fullfile('/somedir/', '*.wav')); 
filenames = {f.name}; 

for idx = 1 : length(IDs) 
    %// Get an ID 
    ID = IDs{idx}; 

    %// Do our checking and filter out those files that don't contain our ID 
    check = regexp(filenames,ID); 
    filtered_ind = cellfun(@isempty, check); 
    final_files = f(~filtered_ind); 

    %// Do your final processing 
    for i = 1:length(final_files) 
     s = final_files(i); %// Get the dir structure for a file that passed the ID check 

     %// Create your structure now... 
     %// ... 
    end 
end 

与上面的代码中,我们打开文本文件,然后分析每个那是在文本文件中的字符串,并将其放置到名为IDs单元阵列。请注意,这些ID现在都是字符串,因此不需要进行任何转换。之后,对于我们的每个ID,我们搜索我们的文件名以查看哪些文件具有我们正在查找的这个ID。我们过滤掉那些没有这个ID的文件名,然后我们遍历这些文件中的每一个并创建我们的结构。我们为每个ID都有这个功能。


只是为了证明这种regexp东西是工作,作为一个小例子,让我们使用您提供与您的帖子三个文件名。我将这些名称放在单元格数组中,然后在我写的代码中运行第3行至第5行,然后我将过滤掉那些不包含我们正在查找的ID的文件名:

filenames = {'1242349_blabla.wav'; 'fdp23424_asdf.wav'; 'o2349_0.wav'}; 
ID = 23424; 
check = regexp(filenames, num2str(ID)); 
filtered_ind = cellfun(@isempty, check); 
final_filenames = filenames(~filtered_ind); 

final_filenames是一个单元格数组,我们的文件名有我们的ID。因此,我们得到:

final_filenames = 

    'fdp23424_asdf.wav' 

祝你好运!