假设我有一个充满文件名的目录,例如:
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,因此内部循环只会进行一次...任何想法?
答案 0 :(得分:1)
我会使用regular expressions来搜索您的单元格数组中ID的出现位置。正则表达式旨在为您搜索特定字符串中的模式。因为你想在一组字符串中搜索特定的数字,我当然会建议你使用它。具体来说,使用regexp
功能,您要搜索的模式是您要搜索的ID。
regexp
的工作原理是你可以提供字符串的单元格数组,输出将是另一个单元格数组,其中每个元素都是一个数字数组,用于确定特定模式所在的起始索引。重新寻找单元格数组中特定字符串的开头。如果数组为空,这意味着我们没有找到任何与您正在寻找的模式相匹配的模式。如果它不是空的,那么它将包含ID在字符串中所在位置的起始索引。这并不重要 - 您想确定ID是否存在于特定字符串中,因此检查每个数组是否为空将是有用的。
因此,考虑到您通过dir
阅读的文件名,我们可以创建一个单独存储文件名的单元格数组,运行regexp
,然后过滤掉那些不在的文件名。 ; t包含您想要的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
但是,您要检查的ID 系列。我们可以简单地使用上面的代码并对其应用循环。换句话说,您可以执行以下操作:
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'
祝你好运!
答案 1 :(得分: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