die Funktion dir
gibt ein Array ähnlich zurück
.
..
Folder1
Folder2
und jedes Mal muss ich die ersten 2 Elemente loswerden, mit Methoden wie:
for i=1:numel(folders)
foldername = folders(i).name;
if foldername(1) == '.' % do nothing
continue;
end
do_something(foldername)
end
und mit verschachtelten Schleifen kann es zu wiederholtem Code kommen.
Kann ich diese "Ordner" also einfacher vermeiden?
Danke für jede Hilfe!
In letzter Zeit habe ich mich einfacher mit diesem Thema befasst:
for i=3:numel(folders)
do_something(folders(i).name)
end
die ersten beiden Punkte einfach ignorieren.
ABER, beachte die Antwort von @Jubobs. Seien Sie vorsichtig bei Ordnernamen, die mit einem unangenehmen Zeichen beginnen, das einen kleineren ASCII - Wert als .
hat. Dann schlägt die zweite Methode fehl. Wenn es mit einem .
beginnt, schlägt die erste Methode fehl :)
Vergewissern Sie sich also entweder, dass Sie Nice-Ordnernamen haben, und verwenden Sie eine meiner einfachen Lösungen, oder verwenden Sie die Lösung von @Jubobs.
Für eine Funktion, die den Verzeichnisinhalt außer .
und ..
enthält, scrollen Sie zum Ende meiner Antwort.
Die Einträge .
und ..
entsprechen dem aktuellen Ordner bzw. dem übergeordneten Ordner. In * nix-Shells können Sie Befehle wie ls -lA
verwenden, um alles außer .
und ..
aufzulisten. Leider bietet MATLABs dir
diese Funktionalität nicht an.
Es ist jedoch nicht alles verloren. Die Elemente des Ausgabestruktur-Arrays, die von der Funktion dir
zurückgegeben werden, sind tatsächlich in lexikografischer Reihenfolge basierend auf dem Feld name
angeordnet. Das bedeutet, wenn Ihr aktueller MATLAB-Ordner Dateien/Ordner enthält, die mit einem beliebigen Zeichen des ASCII -Codepunkts beginnen, der kleiner ist als der Punkt (46, dezimal), dann .
und ..
willl not entsprechen den ersten beiden Elementen dieses Strukturarrays.
Hier ein Beispiel: Wenn Ihr aktueller MATLAB-Ordner die folgende Struktur hat (!hello
und 'world
sind dies Dateien oder Ordner),
.
├── !hello
└── 'world
dann bekommst du das
>> f = dir;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
.
..
Warum sind .
und ..
hier nicht die ersten beiden Einträge? Denn sowohl das Ausrufezeichen als auch das einfache Anführungszeichen haben kleinere Codepunkte (33 bzw. 39 in Dezimalstellen) als die des Punktes (46 in Dezimalzahlen).
Ich verweise Sie auf diese ASCII - Tabelle für eine vollständige Liste der sichtbaren Zeichen, die einen ASCII - Codepunkt haben, der kleiner ist als der Punkt des Punktes; Beachten Sie jedoch, dass es sich nicht notwendigerweise um gültige Dateinamen handelt.
dir
-Funktion, die .
und ..
nicht auflistetDirekt nach dem Aufruf von dir
können Sie die beiden störenden Einträge aus dem struct-Array entfernen, bevor Sie sie bearbeiten. Darüber hinaus können Sie zur Bequemlichkeit immer eine benutzerdefinierte dir
-Funktion schreiben, die das tut, was Sie wollen:
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) = [];
Wenn Sie die gleiche Verzeichnisstruktur wie zuvor annehmen, erhalten Sie Folgendes:
>> f = dir2;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
Eine schleifenlose Lösung:
d=dir;
d=d(~ismember({d.name},{'.','..'}));
Wenn Sie nur dir
verwenden, um eine Liste der Dateien und Verzeichnisse zu erhalten, können Sie stattdessen die Funktion ls
von Matlab verwenden. Auf UNIX-Systemen gibt dies lediglich die Ausgabe des ls
-Befehls der Shell zurück, der möglicherweise schneller ist als der Aufruf von dir
. Die Verzeichnisse .
und ..
werden nicht angezeigt (es sei denn, Ihre Shell ist dafür eingerichtet). Beachten Sie auch, dass sich das Verhalten dieser Funktion zwischen UNIX- und Windows-Systemen unterscheidet.
Wenn Sie weiterhin dir
verwenden möchten und jeden Dateinamen explizit testen möchten, wie in Ihrem Beispiel, ist es ratsam, strcmp
(oder eine seiner Beziehungen) anstelle von ==
zu verwenden. Strings vergleichen. Folgendes würde alle versteckten Dateien und Ordner auf UNIX-Systemen überspringen:
listing = dir;
for i = 1:length(listing)
if ~strcmp(listing(i).name(1),'.')
% Do something
...
end
end
eine ähnliche Lösung aus der von Tal vorgeschlagenen Lösung lautet:
listing = dir(directoryname);
listing(1:2)=[]; % here you erase these . and .. items from listing
Es hat den Vorteil, einen sehr verbreiteten Trick in Matlab zu verwenden, setzt jedoch voraus, dass Sie wissen, dass die ersten beiden Elemente der Liste aufgeführt sind. und .. (was Sie in diesem Fall tun). Während die von Tal angebotene Lösung (die ich nicht ausprobiert habe) das zu finden scheint. und .. Elemente, auch wenn sie nicht an den ersten beiden Positionen der Auflistung platziert werden.
Hoffentlich hilft das ;)
@Jubobs und @Tal-Lösungen kombinieren:
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
Sie können auch andere Dateien als das Entfernen von Punkten ausschließen
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