Search code examples
matlabdir

MATLAB dir without '.' and '..'


the function dir returns an array like

.
..
Folder1
Folder2

and every time I have to get rid of the first 2 items, with methods like :

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

and with nested loops it can result in a lot of repeated code.

So can I avoid these "folders" by an easier way?

Thanks for any help!

Edit:

Lately I have been dealing with this issue more simply, like this :

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

simply disregarding the first two items.

BUT, pay attention to @Jubobs' answer. Be careful for folder names that start with a nasty character that have a smaller ASCII value than .. Then the second method will fail. Also, if it starts with a ., then the first method will fail :)

So either make sure you have nice folder names and use one of my simple solutions, or use @Jubobs' solution to make sure.


Solution

  • TL; DR

    Scroll to the bottom of my answer for a function that lists directory contents except . and ...

    Detailed answer

    The . and .. entries correspond to the current folder and the parent folder, respectively. In *nix shells, you can use commands like ls -lA to list everything but . and ... Sadly, MATLAB's dir doesn't offer this functionality.

    However, all is not lost. The elements of the output struct array returned by the dir function are actually ordered in lexicographical order based on the name field. This means that, if your current MATLAB folder contains files/folders that start by any character of ASCII code point smaller than that of the full stop (46, in decimal), then . and .. willl not correspond to the first two elements of that struct array.

    Here is an illustrative example: if your current MATLAB folder has the following structure (!hello and 'world being either files or folders),

    .
    ├── !hello
    └── 'world
    

    then you get this

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

    Why are . and .. not the first two entries, here? Because both the exclamation point and the single quote have smaller code points (33 and 39, in decimal, resp.) than that of the full stop (46, in decimal).

    I refer you to this ASCII table for an exhaustive list of the visible characters that have an ASCII code point smaller than that of the full stop; note that not all of them are necessarily legal filename characters, though.

    A custom dir function that does not list . and ..

    Right after invoking dir, you can always get rid of the two offending entries from the struct array before manipulating it. Moreover, for convenience, if you want to save yourself some mental overhead, you can always write a custom dir function that does what you want:

    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

    Assuming the same directory structure as before, you get the following:

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