Вопрос или проблема
tree
имеет опцию -d
, которая “список только директорий.
“. Однако, я не могу найти опцию, чтобы “список только файлов.” Я просмотрел man-страницу, но не могу найти опцию для вывода только файлов.
Как другие уже сказали в комментариях, вывод только недиректорий не совсем соответствует цели команды tree
.
Однако, вывод только файлов в текущем каталоге не является чем-то необычным, если вы, как и я, предпочитаете использовать настраиваемый tree
вместо ls
(и, возможно, даже создали алиас ls
для tree
с вашими предпочтительными флагами и аргументами).
Использование комбинации tree
и grep
даст вам нужный результат:
$ tree -F
.
├── file1.txt
├── file5.txt
├── parent_dir1/
│ ├── child_dir/
│ ├── file2.txt
│ └── file3.txt
└── parent_dir2/
└── child_dir2/
└── file4.txt
4 directories, 4 files
$ tree -FL 1 | grep -v /$
.
├── file1.txt
├── file5.txt
2 directories, 1 file
Флаг ‘F’ заставляет tree
добавлять “https://unix.stackexchange.com/” к директориям, а флаг ‘v’ для grep
инвертирует заданный шаблон, который совпадает со всеми строками, заканчивающимися на “https://unix.stackexchange.com/”.
Вы заметите, что даже сводка в конце остается применимой, несмотря на то, что директории фактически не отображаются.
Как только вы опускаетесь более чем на один уровень вниз, структура дерева доминирует и все становится немного странным.
$ tree -FL 3 | grep -v /$
.
├── file1.txt
├── file5.txt
│ ├── file2.txt
│ └── file3.txt
└── file4.txt
4 directories, 4 files
EDIT
Кроме того, если вас беспокоит такая «сломанная» структура дерева (т.е. тот факт, что некоторые файлы предшествуют символу ‘├─’ вместо ‘└─’, а многоуровневая версия кажется незаконченной…), вы можете исправить это, сортируя вывод, сначала директории.
$ tree --dirsfirst -FL 1 | grep -v /$
.
├── file1.txt
└── file5.txt
2 directories, 1 file
$ tree --dirsfirst -FL 3 | grep -v /$
.
│ ├── file2.txt
│ └── file3.txt
│ └── file4.txt
├── file1.txt
└── file5.txt
4 directories, 5 files
Я думаю, это на самом деле делает безузловую структуру дерева более читаемой.
Рассмотрите следующую команду:
tree -ifF /usr/java/default/jre/lib/images | grep -v '/$'
/usr/java/default/jre/lib/images
/usr/java/default/jre/lib/images/cursors/cursors.properties
/usr/java/default/jre/lib/images/cursors/invalid32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_CopyDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_CopyNoDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_LinkDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_LinkNoDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_MoveDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_MoveNoDrop32x32.gif
/usr/java/default/jre/lib/images/icons/sun-java_HighContrastInverse.png
/usr/java/default/jre/lib/images/icons/sun-java_HighContrast.png
/usr/java/default/jre/lib/images/icons/sun-java_LowContrast.png
/usr/java/default/jre/lib/images/icons/sun-java.png
2 directories, 12 files
Аргументы -i
и -f
заставляют tree
выводить полные пути на каждой строке, вместо отступов. Аргумент -F
заставляет его добавлять /
к именам директорий, которые фильтруются инвертированным grep (grep -v '/$'
).
Я часто использую вариант этого для того, чтобы нетерпеливо наблюдать за содержимым выходного каталога (и его подкаталогов) в процессе выполнения другой команды…
watch exec "tree -ifFsD /var/local/myapp/data | grep -v '/$'"
Если вас устраивает ответ, который не использует tree
, я бы рекомендовал find
.
find $DIR -type f
Где $DIR
это каталог, в котором вы хотите искать.
Вы потом могли бы превратить это в формат дерева, если бы захотели.
Вы могли бы создать функцию tree_file
, которая бы делала все это. Благодарность JavaSherrif’у из этого ответа на SO (ссылка ранее) за обработку sed
. Я просто доработал ее для включения UTF символов.
tree_file() {
DIR=${1:-"."}
find $DIR -type f | sed -e "s/[^-][^\/]*\// │/g" -e "s/│\([^ ]\)/│── \1/"
}
старый поток, но так как -F теперь(?) добавляет разные символы для отображения типов файлов:
-F Добавляет
/
для директорий,=
для файлов-сокетов,*
для исполняемых файлов,>
для дверей (Solaris) и `|’ для FIFO, в соответствии с ls -F
команда может выглядеть так:
watch exec "tree -ifFsD /var/local/myapp/data | grep '[[:alnum:]]$\|\*'"
Вы можете рекурсивно перечислить только файлы и отсортировать их с этой командой:
tree -daifv –noreport .|xargs -I {} tree -aifv -L 1 –noreport {}|xargs -I {} find {} -prune -type f
.
Ответ или решение
Использование команды tree
позволяет визуализировать структуру директорий и файлов в виде дерева, что бывает полезно для анализа содержимого каталогов. Однако, в стандартной реализации tree
нет прямой возможности отобразить только файлы без директорий, что вызывает неудобство у пользователей, привыкших к функциональности, аналогичной команде ls
.
Теоретическая основа (Theory)
Команда tree
по своей сути предназначена для отображения всей иерархии содержимого каталога, включая как файлы, так и каталоги, в структурированном виде. Параметр -d
в tree
существует для того, чтобы ограничить вывод только каталогами, исключая файлы. Тем не менее, обратного параметра, который исключает директории, стандартно не предусмотрено. Для достижения подобного эффекта в UNIX-системах применяются комбинации команд tree
и grep
, специально отфильтровывающих вывод.
Команда grep
известна способностью фильтровать текст на основании заданных шаблонов. Вместе с -v
(invert match) позволяет исключать строчки, соответствующие шаблону, что в нашем случае используется для удаления из вывода всех строк, оканчивающихся символом /
, обозначающим директорию.
Практический пример (Example)
Рассмотрим пример использования команды для отображения только файлов:
tree -F | grep -v '/$'
Здесь:
tree -F
— выводит содержимое каталога, добавляя/
после имен каталогов, что помогает отличить их от файлов.grep -v '/$'
— фильтрует (исключая) все строки, которые заканчиваются символом/
.
Такой подход позволяет получить чистый вывод с файлами без перечисления директорий. Вдобавок, если вывод поколений (уровни вложенности) не столь важен, можно использовать ключ -i
для вывода полных путей к файлам:
tree -ifF /path/to/directory | grep -v '/$'
Применение (Application)
Этот подход можно оптимизировать ещё больше, или скриптовать в функции для частого использования. Например, если вы предпочитаете видеть только файлы, вы можете создать функцию в оболочке, такую как Bash:
list_files_only() {
directory=${1:-"."}
tree -ifF "$directory" | grep -v '/$'
}
Эту функцию можно поместить в .bashrc
или эквивалент файл и использовать её в любой момент путем простого вызова list_files_only /desired/path
.
Также, для тех, кто справляется с изменяющейся структурой каталогов, можно рассмотреть возможность использования find
, которая по своей природе более гибка для фильтрации файлов:
find $DIR -type f
find
имеет множество флагов и параметров, которые можно использовать для более изощренных запросов, например, для вывода только исполняемых файлов:
find $DIR -type f -executable
Все описанные техники позволяют адаптировать инструмент под свои нужды, создавая команды или сценарии, которые фокусируются на работе с файлами, избегая избыточной информации о структурах директорий.
Заключение
Итак, хотя tree
не предоставляет стандартного параметра для отображения только файлов, комбинация tree
с grep
или использование find
предоставляют мощные альтернативы для достижения цели. Гармоничное использование команд tree
и grep
позволяет не только решить задачу отображения только файлов, но и интегрировать решение в рабочие процессы, обеспечивая эффективную работу с содержанием директорий.