Подтвердить что ты не робот

MATLAB dir без '.' а также '..'

функция dir возвращает массив вроде

.
..
Folder1
Folder2

и каждый раз, когда мне приходится избавляться от первых двух предметов, с помощью таких методов, как:

for i=1:numel(folders)
    foldername = folders(i).name;
    if foldername(1) == '.' % do nothing
            continue;
    end
    do_something(foldername)
end

и с вложенными циклами, это может привести к многому повторяемому коду.

Итак, могу ли я избежать этих "папок" более простым способом?

Спасибо за любую помощь!

Изменить:

В последнее время я более просто разбираюсь с этой проблемой:

for i=3:numel(folders)
    do_something(folders(i).name)
end

просто игнорируя первые два элемента.

НО, обратите внимание на ответ @Jubobs. Будьте осторожны с именами папок, которые начинаются с неприятного символа с меньшим значением ASCII, чем .. Тогда второй метод не удастся. Кроме того, если он начинается с ., тогда первый метод не будет выполнен:)

Итак, убедитесь, что у вас есть хорошие имена папок и используйте одно из моих простых решений или используйте решение @Jubobs, чтобы убедиться.

4b9b3361

Ответ 1

TL; DR

Прокрутите до конца моего ответа функцию, содержащую содержимое каталога, за исключением . и ...

Подробный ответ

Записи . и .. соответствуют текущей папке и родительской папке соответственно. В командах * nix вы можете использовать команды типа ls -lA для отображения всего, кроме . и ... К сожалению, MATLAB dir не предлагает эту функциональность.

Однако все не потеряно. Элементы выходного массива struct, возвращаемые функцией dir, фактически упорядочены в лексикографическом порядке на основе поля name. Это означает, что если ваша текущая папка MATLAB содержит файлы/папки, которые начинаются с любого символа кодовой точки ASCII меньше, чем у полной остановки (46, в десятичной форме), тогда . и .. willl not соответствуют первым двум элементам этого массива struct.

Вот иллюстративный пример: если ваша текущая папка MATLAB имеет следующую структуру (!hello и 'world - файлы или папки),

.
├── !hello
└── 'world

то вы получите это

>> f = dir;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
.
..

Почему . и .. не первые две записи, здесь? Поскольку как восклицательный знак, так и одинарная кавычка имеют меньшие кодовые точки (33 и 39, в десятичной форме, соответственно), чем точка полного стопа (46, в десятичной форме).

Я отсылаю вас к этой таблице ASCII для исчерпывающего списка видимых символов, которые имеют кодовую точку ASCII, меньшую, чем точка полного стопа; обратите внимание, что не все из них обязательно являются символами законного имени файла.

Пользовательская функция dir, которая не перечисляет . и ..

Сразу после вызова dir вы всегда можете избавиться от двух оскорбительных записей из массива struct, прежде чем манипулировать им. Кроме того, для удобства, если вы хотите сохранить себе некоторые умственные накладные расходы, вы всегда можете написать пользовательскую функцию dir, которая делает то, что вы хотите:

function listing = dir2(varargin)

if nargin == 0
    name = '.';
elseif nargin == 1
    name = varargin{1};
else
    error('Too many input arguments.')
end

listing = dir(name);

inds = [];
n    = 0;
k    = 1;

while n < 2 && k <= length(listing)
    if any(strcmp(listing(k).name, {'.', '..'}))
        inds(end + 1) = k;
        n = n + 1;
    end
    k = k + 1;
end

listing(inds) = [];

Test

Предполагая ту же структуру каталогов, что и раньше, вы получаете следующее:

>> f = dir2;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world

Ответ 2

Решение без петли:

d=dir;
d=d(~ismember({d.name},{'.','..'}));

Ответ 3

Если вы просто используете dir для получения списка файлов и каталогов, вы можете использовать функцию Matlab ls вместо. В системах UNIX это просто возвращает вывод команды ls, которая может быть быстрее, чем вызов dir. Каталоги . и .. не будут отображаться (если только ваша оболочка не настроена для этого). Кроме того, обратите внимание, что поведение этой функции различается между системами UNIX и Windows.

Если вы все еще хотите использовать dir, и вы проверяете каждое имя файла явно, как в вашем примере, это хорошая идея использовать strcmp (или одно из его отношений) вместо == для сравнения строк. Следующее пропустит все скрытые файлы и папку в системах UNIX:

listing = dir;
for i = 1:length(listing)
    if ~strcmp(listing(i).name(1),'.')
        % Do something
        ...
    end
end

Ответ 4

аналогичное решение из предложенного Тэлом:

listing = dir(directoryname);
listing(1:2)=[];   % here you erase these . and .. items from listing

У этого есть преимущество, чтобы использовать очень распространенный трюк в Matlab, но предполагает, что вы знаете, что первые два элемента списка. и.. (что вы делаете в этом случае). В то время как решение, предоставленное Талом (которое я не пытался, хотя), похоже, находит. и.., даже если они не помещены в первые две позиции в листинге.

Надеюсь, что помогает;)

Ответ 5

Вы также можете исключить любые другие файлы, кроме удаления точек

d = dir('/path/to/parent/folder')
d(1:2)=[]; % removing dots 
d = d([d.isdir])    % [d.isdir] returns a logical array of 1s representing folders and 0s for other entries

Ответ 6

Я использовал: a = dir(folderPath);

Затем использовали два коротких кода, которые возвращают struct:

my_isdir = a([a.isdir]) Получить структуру, которая имеет только информацию о папке

my_notdir = a(~[a.isdir]) Получить структуру, которая имеет только информацию о папке