dicominfo - fullfile matlab
MATLAB dir sin ''.'' y ''..'' (7)
la función dir
devuelve una matriz como
.
..
Folder1
Folder2
y cada vez que tengo que deshacerme de los primeros 2 elementos, con métodos como:
for i=1:numel(folders)
foldername = folders(i).name;
if foldername(1) == ''.'' % do nothing
continue;
end
do_something(foldername)
end
y con bucles anidados puede dar lugar a muchos códigos repetidos.
Entonces, ¿puedo evitar estas "carpetas" de una manera más fácil?
¡Gracias por cualquier ayuda!
Editar:
Últimamente he estado tratando este problema de manera más simple, como esto:
for i=3:numel(folders)
do_something(folders(i).name)
end
simplemente sin tener en cuenta los dos primeros elementos.
PERO , presta atención a la respuesta de @Jubobs. Tenga cuidado con los nombres de carpeta que comienzan con un carácter desagradable que tiene un valor ASCII más pequeño que .
. Entonces el segundo método fallará. Además, si comienza con un .
, entonces el primer método fallará :)
Entonces, asegúrate de tener buenos nombres de carpetas y de usar una de mis soluciones simples, o usa la solución de @Jubobs para asegurarte.
TL; DR
Desplácese hasta el final de mi respuesta para ver una función que enumera los contenidos del directorio excepto .
y ..
Respuesta detallada
El .
y ..
entradas corresponden a la carpeta actual y la carpeta principal, respectivamente. En shells * nix, puede usar comandos como ls -lA
para listar todo pero .
y ..
Lamentablemente, el dir
de MATLAB no ofrece esta funcionalidad.
Sin embargo, no todo está perdido. Los elementos de la matriz de estructura de salida que devuelve la función dir
están ordenados en orden lexicográfico según el campo de name
. Esto significa que, si su carpeta MATLAB actual contiene archivos / carpetas que comienzan con cualquier carácter de punto de código ASCII más pequeño que el de la parada completa (46, en decimal), entonces .
y ..
no corresponderá con los dos primeros elementos de la estructura de esa estructura.
Este es un ejemplo ilustrativo: si su carpeta actual de MATLAB tiene la siguiente estructura ( !hello
y ''world
son archivos o carpetas),
.
├── !hello
└── ''world
entonces obtienes esto
>> f = dir;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
''world
.
..
Por que son y ..
no las dos primeras entradas, aqui? Debido a que tanto el signo de exclamación como la comilla simple tienen puntos de código más pequeños (33 y 39, en decimal, resp.) Que los de la parada completa (46, en decimal).
Le remito a esta tabla ASCII para obtener una lista exhaustiva de los caracteres visibles que tienen un punto de código ASCII más pequeño que el de la parada completa; tenga en cuenta que no todos ellos son necesariamente caracteres de nombre de archivo legales, sin embargo.
Una función dir
personalizada que no lista .
y ..
Justo después de invocar dir
, siempre puede deshacerse de las dos entradas ofensivas de la estructura de estructura antes de manipularlo. Además, por conveniencia, si desea ahorrarse una sobrecarga mental, siempre puede escribir una función dir
personalizada que haga lo que quiera:
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) = [];
Prueba
Suponiendo la misma estructura de directorios que antes, obtienes lo siguiente:
>> f = dir2;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
''world
Combinando soluciones @jubobs y @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
Si solo está usando dir
para obtener una lista de archivos y directorios, puede usar la función ls
de Matlab. En los sistemas UNIX, esto solo devuelve la salida del comando ls
del shell, que puede ser más rápido que llamar a dir
. El .
y ..
directorios no se mostrarán (a menos que su shell esté configurado para hacerlo). Además, tenga en cuenta que el comportamiento de esta función es diferente entre los sistemas UNIX y Windows.
Si aún desea usar dir
, y prueba cada nombre de archivo explícitamente, como en su ejemplo, es una buena idea usar strcmp
(o una de sus relaciones) en lugar de ==
para comparar cadenas. Lo siguiente omitiría todos los archivos y carpetas ocultos en los sistemas UNIX:
listing = dir;
for i = 1:length(listing)
if ~strcmp(listing(i).name(1),''.'')
% Do something
...
end
end
También puede excluir cualquier otro archivo además de eliminar puntos.
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
Una solución similar a la sugerida por Tal es:
listing = dir(directoryname);
listing(1:2)=[]; % here you erase these . and .. items from listing
Tiene la ventaja de usar un truco muy común en Matlab, pero asume que usted sabe que los dos primeros elementos del listado son. y .. (lo que haces en este caso). Mientras que la solución provista por Tal (que no probé) parece encontrar el. y .. artículos incluso si no están ubicados en las dos primeras posiciones dentro del listado.
Espero que ayude ;)
Utilicé: a = dir(folderPath);
Luego usé dos códigos cortos que devuelven la estructura:
my_isdir = a([a.isdir])
Obtiene una estructura que solo tiene información de carpeta
my_notdir = a(~[a.isdir])
Obtiene una estructura que solo tiene información que no es de carpeta
Una solución sin bucles:
d=dir;
d=d(~ismember({d.name},{''.'',''..''}));