String MATLAB:只选择与某些输入字符串相一致的文件名

String MATLAB:只选择与某些输入字符串相一致的文件名,string,matlab,struct,cell,String,Matlab,Struct,Cell,假设我有一个满是文件名的目录,例如: 1242349_blabla.wav fdp23424_asdf.wav o2349_0.wav 我有一个输入文本文件,列出了每个换行符上的唯一ID,这些ID与这些文件名中的数字一致(例如,上面第二个文件名为“23424”) 我想构造一个文件名结构,其中只包含该目录中与输入文本文件中的某个ID一致的文件名: fid = fopen('input.txt'); input = textscan(fid, '%s', 'Delimiter', '\n');

假设我有一个满是文件名的目录,例如:

1242349_blabla.wav
fdp23424_asdf.wav
o2349_0.wav
我有一个输入文本文件,列出了每个换行符上的唯一ID,这些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 
但是,对于“cell”类型的输入参数,我得到了错误“undefined function'ne”。我尝试了很多选择,但都没有用。此外,输入计算为一个38x1单元,但长度为1,因此内部循环只运行一次。。。有什么想法吗?

我会用它来搜索单元格数组中出现的ID。正则表达式设计用于为您搜索特定字符串中的模式。因为您想在一组字符串中搜索特定的数字,我当然建议您使用它。具体来说,使用函数,您要搜索的模式就是您要搜索的ID

regexp
的工作原理是,您可以提供一个字符串单元格数组,并且输出将是另一个单元格数组,其中每个元素都是一个数字数组,用于确定您要查找的特定模式从单元格数组中的特定字符串开始的起始索引。如果数组为空,这意味着我们找不到任何与您要查找的匹配的模式。如果它不是空的,那么它将包含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);
%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
第一行代码从所需目录中读取文件。第二行代码从结构的每个
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'

祝你好运

正则表达式无疑是最灵活、最强大的解决方案。但是,如果您的需求更简单……您可以做一些更简单的事情,比如在
dir
命令中使用通配符。试着这样做:

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);
%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

您应该始终使用
isempty
函数,而不是MATLAB中的
=[]