Напишем скрипт Bash для построения дерева каталогов для репозитория в
файле Markdown. Будем использовать только средства Bash и базовое ПО Linux
— ls
, sed
, tr
и echo
— без дополнительных программ. Полученный файл
DIRECTORY_TREE.md
будем использовать в вёб-интерфейсе для навигации по объектам репозитория.
Создаём рекурсивную функцию и с её помощью обходим все файлы и каталоги репозитория, за
исключением списка из .gitignore
— строим структуру каталогов в форме дерева. Выводим
элементы в виде ссылок <a>
, сворачиваем папки с одним вложенным элементом в одну строку,
помещаем собранное дерево в контейнер <pre>
и добавляем заголовок — в результате получаем
краткий и лаконичный файл Markdown со ссылками.
#!/bin/bash
# отсортированный список файлов и каталогов
function list_directory_contents {
# сначала заглавные буквы, потом строчные, сначала каталоги, потом файлы
eval "LC_COLLATE=C ls -A --group-directories-first $exclusions $1"
}
# дерево каталогов со ссылками
function directory_tree {
# аргументы
local path="$1"
local head="$2"
local tail="$3"
# префикс для текущего элемента
if [ "one" == "$4" ]; then
echo -n "/"
else
echo -ne "\n$head"
fi
# текущий элемент дерева
echo -n "<a href='${path#*/}'>${path##*/}</a>"
# рекурсивные вызовы для подкаталогов
if [ -d "$path" ]; then
local list # массив файлов и каталогов
readarray -t list <<<"$(list_directory_contents "$path")"
local size=${#list[@]} # длина массива
local i # счётчик
for ((i = 0; i < size; i++)); do
if [ -z "${list[$i]}" ]; then
continue # пропустить пустой каталог
elif ((size == 1)); then
directory_tree "$path/${list[$i]}" "$tail" "$tail" "one"
elif ((i < size - 1)); then
directory_tree "$path/${list[$i]}" "$tail├─ " "$tail│ "
else
directory_tree "$path/${list[$i]}" "$tail└─ " "$tail "
fi
done
fi
}
# строка исключений для "ls" из списка ".gitignore" — неотслеживаемые файлы
exclusions="-I'.git' $(sed -E "s|^(.*)$|-I'\1'|" .gitignore | tr '\n' ' ')"
# помещаем дерево в контейнер, добавляем заголовок и выводим в файл
{
echo "## Дерево каталогов"
echo -ne "\n<pre>"
directory_tree .
echo -e "\n</pre>"
} >DIRECTORY_TREE.md
Запускаем скрипт в корне репозитория и сохраняем полученный файл.
© Головин Г.Г., Код с комментариями, 2023