zaLinux.ru

Как вывести список только директорий используя ls в Bash


Для обработки в скриптах может понадобиться в определённой директории получить только список только папок без файлов. Далее показано, как это сделать разными способами.

1. С помощью ls увидеть все папки кроме скрытых

*/ - это шаблон, который соответствует всем подкаталогам в текущем каталоге (* будет соответствовать всем файлам и подкаталогам; / ограничивает его каталогами). Точно так же, чтобы вывести список всех подкаталогов в /home/mial/bin/aur, используйте:

ls -d /home/mial/bin/aur/*/

Чтобы вывести только каталоги в текущей папке:

ls -d */

Чтобы вывести данные в столбик:

ls -1 -d */

2. С помощью ls увидеть все папки вместе со скрытыми

Обратите внимание, что */ не найдёт любые скрытые папки. Чтобы включить и их, укажите их явно:

ls -d .*/ */

Обратите внимание, что в примере выше используется два шаблона. Чтобы это стало очевидным, рассмотрим следующий пример: нужно показать только каталоги, в том числе и скрытые в директории /home/mial/bin/aur/:

ls -d /home/mial/bin/aur/.*/ /home/mial/bin/aur/*/

3. С помощью ls и cut

Следующий способ показывает каталоги только в текущей папке, но делает это в виде столбика:

ls -d */ | cut -f1 -d'/'

Чтобы показать вместе со скрытыми каталогами:

ls -d .*/ */ | cut -f1 -d'/'

Чтобы показать только директории в папке /home/mial/bin/aur:

ls -d /home/mial/bin/aur/*/ | cut -f1 -d'/'

4. Используя echo

Этот способ не рекомендуется, если в именах папках могут быть пробелы:

Пример показа всех папок кроме скрытых:

echo */

Показ всех скрытых и обычных директорий:

echo .*/ */

Показ всех скрытых и обычных папок в директории /home/mial/bin/aur/:

echo /home/mial/bin/aur/.*/ /home/mial/bin/aur/*/

5. Используя ls и grep

В этом варианте применяется фильтрация вывода с помощью grep. Этот способ имеет ограничение — папки должны выводиться в виде подробного списка:

ls -l | grep "^d"

Чтобы показать вместе со скрытыми папками:


ls -al | grep "^d"

Для вывода только имён директорий (возможны проблемы с директориями, имеющими пробелы в названиях):


ls -l | grep "^d" | cut -f 10 -d ' '

6. С помощью find

Команда find имеет очень гибкие критерии поиска.

Чтобы вывести все папки без подпапок (замените /home/mial/bin/aur/ на интересующую папку):

find /home/mial/bin/aur/ -maxdepth 1 -type d

Чтобы вывести все папки с подбапками:

find /home/mial/bin/aur/ -type d

7. printf

Чтобы вывести все директории на отдельных строках (аналогично -1)

printf "%s\n" */

Предыдущий пример работает правильно с именами "-", пробелами и переводами строк (newline).

Улучшенный пример, удаляет последний слэш (/), правильно работает с именами, содержащими пробелы и переводы строк:

set -- */; printf "%s\n" "${@%/}"

Пример с функцией. Наконец, использование списка аргументов внутри функции не повлияет на список аргументов текущей запущенной оболочки:

listdirs(){ set -- */; printf "%s\n" "${@%/}"; }

Для запуска функции:

listdirs

Связанная статья: Инструкция по использованию printf в Bash для форматирования и вывода данных


8. tree

Команда tree также полезна для рассматриваемого вопроса. По умолчанию она показывает все файлы и каталоги на полную глубину, а некоторые символы ascii показывают дерево каталогов.

tree

Но если мы хотим получить только каталоги, без дерева ascii и с полным путём из текущего каталога, вы можете сделать:

tree -dfi

Используемые аргументы:

-d	Список только каталогов.
-f	Печатает префикс полного пути для каждого файла.
-i	Делает так, что tree не печатать строки отступа, полезно, когда используется вместе с опцией -f.

И если вам нужен абсолютный путь, вы можете начать с указания полного пути к текущему каталогу:

tree -dfi "$(pwd)"

А чтобы ограничить количество подкаталогов, вы можете установить максимальный уровень подкаталогов с уровнем -L, например:

tree -dfi -L 1 "$(pwd)"

9. Пример скрипта: выполнение действие только с каждой папкой в директории

Следующий скрипт показывает, как можно выполнить действие с каждой папкой в директории — имя каждой папки будет присваиваться переменной $line:

while read -r line ; do
	# echo $line
	# КОД
	# КОД
	# КОД
done < <(ls -d */)

Чтобы выполнить действие с каждой папкой в директории /home/mial/bin/aur:

while read -r line ; do
	# echo $line
	# КОД
	# КОД
	# КОД
done < <(ls -d /home/mial/bin/aur/*/)

Рекомендуемые статьи:

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *