Shell script для создания статического списка каталогов HTML

Итак, я создаю сайт GitHub Pages, чтобы перечислить все Gifs в jglovier/gifs repo. Страницы GH работают только с статическими HTML/CSS/JS или Jekyll, поэтому я не могу использовать листинг каталога apache или любой другой вариант, сгенерированный сервером.

Итак, что я хотел бы сделать, это запустить script в командной строке и просмотреть его для каталогов, перечислить все файлы внутри (которые идут только на один уровень) и вывести их в html ul > li > a, или что-то похожее на это:

root/
|
├── accidents/
|   ├── accident2.gif
|   ├── accident3.gif
|   └── accident4.gif
├── bears/
|   ├── bears1.gif
|   ├── bears2.gif
|   └── bears3.gif
└── cats/
    ├── cat1.gif
    ├── cat2.gif
    └── cat3.gif

Я хотел бы, чтобы значения href были относительными путями для сайта (т.е. href="/cats/cat.gif ), and I need it to output into _includes/site-index.html , which will get pulled into a Jekyll layout file that wraps around my index.md file and generates index.html` on build.

I нашел этот другой вопрос, который очень схож, и попытался реализовать его для моих целей, но, увы, я слишком много из shell n00b для выполнения это само по себе.

Ответ 1

#!/bin/bash

ROOT=/tmp/test
HTTP="/"
OUTPUT="_includes/site-index.html" 

i=0
echo "<UL>" > $OUTPUT
for filepath in `find "$ROOT" -maxdepth 1 -mindepth 1 -type d| sort`; do
  path=`basename "$filepath"`
  echo "  <LI>$path</LI>" >> $OUTPUT
  echo "  <UL>" >> $OUTPUT
  for i in `find "$filepath" -maxdepth 1 -mindepth 1 -type f| sort`; do
    file=`basename "$i"`
    echo "    <LI><a href=\"/$path/$file\">$file</a></LI>" >> $OUTPUT
  done
  echo "  </UL>" >> $OUTPUT
done
echo "</UL>" >> $OUTPUT

My/tmp/test

/tmp/test
├── accidents
│   ├── accident2.gif
│   ├── accident3.gif
│   └── accident4.gif
├── bears
│   ├── bears1.gif
│   ├── bears2.gif
│   ├── bears3.gif
│   └── bears4.gif
└── cats
    ├── cats1.gif
    └── cats2.gif

Полученный результат

<UL>
  <LI>accidents</LI>
  <UL>
    <LI><a href="/accidents/accident2.gif">accident2.gif</a></LI>
    <LI><a href="/accidents/accident3.gif">accident3.gif</a></LI>
    <LI><a href="/accidents/accident4.gif">accident4.gif</a></LI>
  </UL>
  <LI>bears</LI>
  <UL>
    <LI><a href="/bears/bears1.gif">bears1.gif</a></LI>
    <LI><a href="/bears/bears2.gif">bears2.gif</a></LI>
    <LI><a href="/bears/bears3.gif">bears3.gif</a></LI>
    <LI><a href="/bears/bears4.gif">bears4.gif</a></LI>
  </UL>
  <LI>cats</LI>
  <UL>
    <LI><a href="/cats/cats1.gif">cats1.gif</a></LI>
    <LI><a href="/cats/cats2.gif">cats2.gif</a></LI>
  </UL>
</UL>

Вы также можете расширить UL с помощью href, но я не был уверен, что это вам нужно.

echo "  <UL><a href=\"/$path\">$path</a>" >> $OUTPUT

Вам нужно будет запустить это в родительской папке _includes

Ответ 2

Достаточно просто, без пустых директорий (хотя может быть пустым в конце script и добавлять их в любом случае)

#!/bin/bash
root="root"
echo "<ul>"
for file in "$root"/*/*; do
  parentpath="${file#*/}"
  parent="${parentpath%/*}"
  filename="${file##*/}"
  if [[ -z $oldparent ]]; then
    echo "  <li> $parent </li>" && oldparent="$parent"
    echo "  <ul>"
  elif [[ $oldparent != $parent ]]; then
    echo "  </ul>"
    echo "  <li> $parent </li>" && oldparent="$parent"
    echo "  <ul>"
  fi
  echo "    <li><a href=\"$parentpath\">$filename</a></li>"
done
echo "  </ul>"
echo "</ul>" 

например.

$ ./abovescript
<ul>
  <li> accidents </li>
  <ul>
    <li><a href="accidents/accident2.gif">accident2.gif</a></li>
    <li><a href="accidents/accident3.gif">accident3.gif</a></li>
    <li><a href="accidents/accident4.gif">accident4.gif</a></li>
  </ul>
  <li> bears </li>
  <ul>
    <li><a href="bears/bears1.gif">bears1.gif</a></li>
    <li><a href="bears/bears2.gif">bears2.gif</a></li>
    <li><a href="bears/bears3.gif">bears3.gif</a></li>
  </ul>
  <li> cats </li>
  <ul>
    <li><a href="cats/cats1.gif">cats1.gif</a></li>
    <li><a href="cats/cats2.gif">cats2.gif</a></li>
    <li><a href="cats/cats3.gif">cats3.gif</a></li>
  </ul>
</ul>

Ответ 3

Я знаю, что он сказал, что использует оболочку script, но почему бы не использовать Jekyll для этого. Страницы Github автоматически создают сайт jekyll на каждом коммите, поэтому вы можете настроить его и забыть об этом.

Основной пример

---
---

<head>
  <title>Index of /</title>
</head>

<body>
  <h1>Index of /</h1>
  <ul>
    {% for url in site.static_files %}
    <li><a href="{{ site.baseurl | escape }}{{ url.path | escape }}">{{ url.path | escape }}</a> </li>
    {% endfor %}
  </ul>
</body>

Дерево каталогов

---
---
<h1>Index of ./</h1>
<ul></ul>

<style>body{background:#303030;margin:0;font-family:Roboto,Helvetica,Arial,sans-serif;overflow:hidden;display:flex;flex-direction:column;height:100%;width:100%}*{color:#fff;text-decoration:none}h1{background:#ff1959;font-size:1.3125rem;font-weight:500;line-height:64px;padding:0 20px;box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);margin:0}h1+ul{height:100%;padding:20px;overflow-y:auto;overflow-x:hidden}.folder>a:nth-child(1){height:15px;display:inline-block}.folder>a:nth-child(1):hover{text-decoration:underline;text-decoration-color:#ff1959}.file{position:relative;height:50px}.file a{position:absolute;display:inline-block;height:calc(100% - 20px);width:100%;font-size:1rem;font-weight:400;line-height:30px;padding:0 10px;padding-top:4px;margin:10px 0;transition:background-color .5s ease;color:#ff6892}.file:hover a{background-color:rgba(255,255,255,.1)}ul,ul.tree ul{list-style:none;margin:0;padding:0}li{display:block}ul ul{margin-left:10px}ul li{margin:0;padding:0 20px;color:#369;border-left:1px solid #ff1959}ul li:last-child{border-left:none}ul li:before{position:relative;height:28px;width:20px;color:#fff;border-bottom:1px solid #ff1959;content:"";display:inline-block;left:-20px}ul li:last-child:before{border-left:1px solid #ff1959}</style><script>var c=document.getElementsByTagName("ul")[0];function escapeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}for(var files=[{% for url in site.static_files %}'{{ url.path | replace: "'", "\'" }}',{% endfor %}],i=0;i<files.length;i++){var url=files[i].split("/").slice(1);console.group(files[i]);for(var x=0;x<url.length;x++){var file=url[x];if(file)for(var element=null,parent=null,y=0;y<x+1;y++){var el=document.querySelector("[ref="+JSON.stringify(y+"-"+url[y])+"]");if(!el){var type="folder";url[y].indexOf(".")>-1&&(type="file"),el=document.createElement("li");var a=document.createElement("a");a.innerHTML=escapeHtml(url[y]),a.href=url.slice(0,x+1).join("/"),el.appendChild(a),el.setAttribute("ref",y+"-"+url[y]),el.setAttribute("level",y),el.setAttribute("class",type),parent?parent.appendChild(el):c.appendChild(el)}parent=el}}console.groupEnd(files[i])}document.title=document.querySelector("h1").innerHTML+=" ("+files.length+" items)"</script>

введите описание изображения здесь