webentwicklung-frage-antwort-db.com.de

MATLAB-Verzeichnis ohne '.' und '..'

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!

Bearbeiten:

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.

20
jeff

TL; DR

Für eine Funktion, die den Verzeichnisinhalt außer . und .. enthält, scrollen Sie zum Ende meiner Antwort.

Ausführliche 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.

Eine benutzerdefinierte dir-Funktion, die . und .. nicht auflistet

Direkt 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) = [];

Prüfung

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
15
jubobs

Eine schleifenlose Lösung:

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

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
3
horchler

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

2
LeChat

@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
1

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
0
Ahmed Abobakr