Как сделать так, чтобы дерево выводило только файлы?

Вопрос или проблема

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 позволяет не только решить задачу отображения только файлов, но и интегрировать решение в рабочие процессы, обеспечивая эффективную работу с содержанием директорий.

Оцените материал
Добавить комментарий

Капча загружается...