la fonction dir
retourne un tableau comme
.
..
Folder1
Folder2
et à chaque fois je dois me débarrasser des 2 premiers éléments, avec des méthodes comme:
for i=1:numel(folders)
foldername = folders(i).name;
if foldername(1) == '.' % do nothing
continue;
end
do_something(foldername)
end
et avec des boucles imbriquées, il peut en résulter beaucoup de code répété.
Alors, puis-je éviter ces "dossiers" par un moyen plus simple?
Merci pour toute aide!
Dernièrement, j'ai traité ce problème plus simplement, comme ceci:
for i=3:numel(folders)
do_something(folders(i).name)
end
sans tenir compte des deux premiers éléments.
MAIS, faites attention à la réponse de @Jubobs. Faites attention aux noms de dossier commençant par un caractère désagréable dont la valeur ASCII est inférieure à .
. Ensuite, la seconde méthode échouera. De plus, si elle commence par un .
, la première méthode échouera :)
Donc, soit vous assurez que vous avez des noms de dossiers Nice et utilisez l'une de mes solutions simples, soit vous utilisez la solution de @Jubobs pour vous en assurer.
Faites défiler jusqu'au bas de ma réponse pour une fonction qui répertorie le contenu du répertoire sauf .
et ..
.
Les entrées .
et ..
correspondent au dossier actuel et au dossier parent, respectivement. Dans les shells * nix, vous pouvez utiliser des commandes telles que ls -lA
pour tout lister sauf .
et ..
. Malheureusement, la variable dir
de MATLAB n'offre pas cette fonctionnalité.
Cependant, tout n'est pas perdu. Les éléments du tableau struct de sortie renvoyé par la fonction dir
sont en réalité classés dans l'ordre lexicographique en fonction du champ name
. Cela signifie que, si votre dossier MATLAB actuel contient des fichiers/dossiers commençant par un caractère de point de code ASCII inférieur à celui de l'arrêt complet (46, en décimal), alors .
et ..
seront pas. correspondent aux deux premiers éléments de ce tableau struct.
Voici un exemple illustratif: si votre dossier MATLAB actuel a la structure suivante (!hello
et 'world
étant des fichiers ou des dossiers),
.
├── !hello
└── 'world
alors vous obtenez ceci
>> f = dir;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
.
..
Pourquoi .
et ..
ne sont-ils pas les deux premières entrées, ici? Parce que le point d'exclamation et le guillemet simple ont des points de code plus petits (33 et 39, en décimal, resp.) Que ceux du point final (46, en décimal).
Je vous renvoie à ce tableau ASCII pour une liste exhaustive des caractères visibles ayant un point de code ASCII inférieur à celui de l'arrêt complet; Notez que tous ne sont pas nécessairement des caractères de nom de fichier légaux, cependant.
dir
qui ne répertorie pas .
et ..
Immédiatement après avoir appelé dir
, vous pouvez toujours supprimer les deux entrées incriminées du tableau struct avant de le manipuler. De plus, pour plus de commodité, si vous souhaitez vous épargner une surcharge mentale, vous pouvez toujours écrire une fonction personnalisée dir
qui fait ce que vous voulez:
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) = [];
En supposant la même structure de répertoires qu'avant, vous obtenez ce qui suit:
>> f = dir2;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
Une solution sans boucle:
d=dir;
d=d(~ismember({d.name},{'.','..'}));
Si vous utilisez simplement dir
pour obtenir une liste de fichiers et de répertoires, vous pouvez utiliser la fonction ls
de Matlab. Sur les systèmes UNIX, cela renvoie simplement le résultat de la commande ls
du shell, laquelle peut être plus rapide que d'appeler dir
. Les répertoires .
et ..
ne seront pas affichés (à moins que votre shell ne soit configuré pour le faire). Notez également que le comportement de cette fonction est différent entre les systèmes UNIX et Windows.
Si vous souhaitez toujours utiliser dir
et tester chaque nom de fichier de manière explicite, comme dans votre exemple, il est judicieux d'utiliser strcmp
(ou l'une de ses relations) au lieu de ==
comparer des chaînes. Les éléments suivants ignoreraient tous les fichiers et dossiers cachés sur les systèmes UNIX:
listing = dir;
for i = 1:length(listing)
if ~strcmp(listing(i).name(1),'.')
% Do something
...
end
end
une solution similaire à celle proposée par Tal est:
listing = dir(directoryname);
listing(1:2)=[]; % here you erase these . and .. items from listing
Il a l'avantage d'utiliser un truc très courant dans Matlab, mais suppose que vous sachiez que les deux premiers éléments de liste sont. et .. (ce que vous faites dans ce cas). Alors que la solution fournie par Tal (que je n’ai pas essayée cependant) semble trouver le. et .. les articles même s'ils ne sont pas placés aux deux premiers postes de la liste.
J'espère que cela pourra aider ;)
Combinaison des solutions @jubobs et @Tal:
function d = dir2(folderPath)
% DIR2 lists the files in folderPath ignoring the '.' and '..' paths.
if nargin<1; folderPath = '.'; elseif nargin == 1
d = dir(folderPath);
d = d(~ismember({d.name},{'.','..'}));
end
Vous pouvez également vouloir exclure d'autres fichiers en plus de supprimer les points
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