Есть ли правильный способ перечислить подкаталоги текущего каталога?
10
Я могу найти подкаталоги каталога по
ls -d --*/
или
ls -l | grep "^d"
но оба они кажутся косвенными, и я думаю, что был бы стандартный способ найти только каталоги. Есть ли правильный способ сделать это? И если нет, то приведет ли это к нежелательному поведению в крайних случаях? (Символические ссылки, скрытые каталоги и т. Д.)
Ответ будет зависеть больше от того, что вы намереваетесь сделать с выходом, чем от того, что вы ищете. Если вы просто хотите увидеть список для визуальной справки в терминале, ваше первое решение на самом деле довольно приятно. Если вы хотите обработать вывод, вы должны использовать другой метод.
Один из самых надежных способов получить список для передачи в другую программу - это использовать find.
find -maxdepth 1-type d
Причина, по которой это хорошо для каналов, заключается в том, что они findмогут выводить данные, разделенные нулями, используя -print0или должным образом экранируя строки в качестве аргументов для других программ, использующих -exec. Для справки о том, почему это лучше, чем анализ выходных данных ls, смотрите ParsingLS на вики Грега.
Мне пришлось печатать, find . -maxdepth 1 -type dчтобы заставить это работать на OS X Yosemite.
Шон Левин
1
для вывода списка подкаталогов необходимо также указать -mindepth, как в find . -maxdepth 1 -mindepth 1 -type d. В противном случае текущий каталог .будет включен.
tinlyx
5
К вашему сведению - в ZSH (но не в BASH) вы также можете сделать это ls -d -- *(/):; модификатор говорит ЗШ только Глобы каталогам.(/)
Тем не менее, оно не сильно отличается от предложенного вами решения ( ls -d -- */) и далеко не стандартно.
Что касается вывода ls(который, вероятно, отличается в зависимости от других флагов):
% ls
dir0 dir1 dir2 file0 file1 file2
% ls -d --*/
dir0/ dir1/ dir2/% ls -d --*(/)
dir0 dir1 dir2
zsh расширяет звездочку на все файлы и каталоги, флаг (/) выбирает части этого расширения, поэтому ls * (/) также будет работать, как и echo * (/) , или более zshly способ печати -l * (/ ) . Две первые версии также работают в bash.
Тор
1
Обратите внимание, что *(/)расширяется на не скрытые каталоги, а */расширяется на не скрытые каталоги или символические ссылки на каталоги (или, по крайней мере, символические ссылки на пути, для которых мы можем сказать, что они являются каталогами).
find . -maxdepth 1 -type d
чтобы заставить это работать на OS X Yosemite.find . -maxdepth 1 -mindepth 1 -type d
. В противном случае текущий каталог.
будет включен.К вашему сведению - в ZSH (но не в BASH) вы также можете сделать это
ls -d -- *(/)
:; модификатор говорит ЗШ только Глобы каталогам.(/)
Тем не менее, оно не сильно отличается от предложенного вами решения (
ls -d -- */
) и далеко не стандартно.Что касается вывода
ls
(который, вероятно, отличается в зависимости от других флагов):источник
*(/)
расширяется на не скрытые каталоги, а*/
расширяется на не скрытые каталоги или символические ссылки на каталоги (или, по крайней мере, символические ссылки на пути, для которых мы можем сказать, что они являются каталогами).