bash脚本用于创建HTML导航菜单

时间:2013-11-28 21:51:34

标签: bash

前段时间我写了一个javascript程序来遍历目录树,并从树的前3个级别构建一个html nav菜单文件。我现在正在尝试使用bash复制它,因为JS程序需要IE浏览器和activeX来运行。我对bash来说相当新,所以这对我来说是一次很棒的学习经历。

所以,我所拥有的结构如下:

-Folder A
    --Folder B
    --Folder C
         --Folder C1
         --Folder C2
               --Folder CC1
    --Folder D
         --Folder D1
    --Folder E

等。你明白了。无论如何,文件夹名称各不相同,但每个文件夹中都有一个名为“foldername.txt”的文本文件。在此文件中有一行文本,其中包含要在菜单上使用的实际文件夹名称(这是由于某些名称的长度)。

因此,我尝试将每个文件夹/子文件夹循环到第3级,读取文件夹中的每个foldername.txt文件并返回名称,同时保持文件夹层次结构。我希望这是有道理的。输出附加了html标记并回显到.htm文件。

到目前为止,我尝试过不同的事情。下面的代码几乎可以实现我想要的,它将扫描目录并根据文本文件返回名称,但不保持层次结构。遗憾的是,我没有包含-maxdepth的find版本。正如你所看到的,我已经尝试过嵌套循环,因为它只有3个深度,但每个级别的递归都会继续,这样我就会得到重复和奇怪的结果。

#!/bin/bash

ROOT=/data/
OUTPUTFILE=${ROOT}/Menu-test.html

# Create first level items - these are static
HEADING="<UL class=navlist1>
<LI><SPAN class=plus><p>-</p></SPAN><A class=''>Level 1 products</A></LI>"

END="</UL>"
L2="<UL class=navlist2>"
L3="<UL class=navlist3>"
LI="<LI><SPAN class=plus><P>+</P></SPAN>"
LIEND="</LI>"

echo $HEADING > $OUTPUTFILE;

# set shell options
shopt -s nullglob

# loop through top level dir
for d in $DIR/*/
do
    for file in $(find $d -name "foldername.txt");
    do
        OUT=$(awk '{ print $0 }' $file)
        echo $LI$OUT$LIEND >> $OUTPUTFILE; 
    done

    # loop through second level dir
    for e in $d/*/
        do
            echo $L2 >> $OUTPUTFILE;
            for file2 in $(find $e -type f -name "foldername.txt");
                do
                    OUT2=$(awk '{ print $0 }' $file2)
                    echo $LI$OUT2$LIEND >> $OUTPUTFILE; 
                done
            echo $END >> $OUTPUTFILE;

                # loop through third level dir
                for f in $e/*/
                    do
                        echo $L3 >> $OUTPUTFILE;
                        for file3 in $(find $f -type f -name "foldername.txt");
                            do
                                OUT3=$(awk '{ print $0 }' $file3)
                                echo $LI$OUT3$LIEND >> $OUTPUTFILE; 
                            done
                        echo $END >> $OUTPUTFILE;
                    done
        done
done
echo $END >> $OUTPUTFILE;

对于长篇文章和凌乱的代码感到抱歉,但我真的想先尝试自己这样做,因为这是我学习最好的方法。所以关于如何让它发挥作用的任何想法。请注意,我无法访问Python或任何其他语言,因此请将其删除。

我正在寻找的输出如下所示(连字符只是为了保持格式化而不在输出中):

**<LI><SPAN class=plus><P>+</P></SPAN><A href=''>**
<UL class='navlist1'> 
    <LI><SPAN class='plus'><p>-</p></SPAN><A class=''>Folder A</A> 
        <UL class='navlist2' style='display:block'> 
            <LI><SPAN class='bull'><p class='bull'>&bull;</p></SPAN><A href='http://www.somewhere.com/index.htm'>Folder A1</A></LI> 
            <LI><SPAN class='bull'><p class='bull'>&bull;</p></SPAN><A href='http://www.somewhere.com/index.htm'>Folder A2</A></LI> 
            <LI><SPAN class='bull'><p class='bull'>&bull;</p></SPAN><A href='http://www.somewhere.com/index.htm'>Folder A3</A></LI> 
        </UL**></A>
    <UL class=navlist1>**
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder B</A></LI>
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder C</A></LI>
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D</A></LI>
           <UL class=navlist2>
                <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1</A>
                    <UL class=navlist3>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1A</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1B</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1C</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1D</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D1E</A></LI>
                    </UL>
                </LI>
                <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D2</A>
                    <UL class=navlist3>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D2A</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D2B</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder D2C</A></LI>
                    </UL>
                </LI>
            </UL>
        </LI>
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder E</A></LI>
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder F</A></LI>
        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G</A></LI>
            <UL class=navlist2>
                <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G1</A>
                    <UL class=navlist3>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G1A</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G1B</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G1C</A></LI>
                        <LI><SPAN class=plus><P>+</P></SPAN><A href=''>Folder G1D</A></LI>
                    </UL>
                </LI>
            </UL>
        </LI>
    </UL>
**</LI>**

所以,这是当前的工作输出。我还需要做的是在每个子文件夹中包含href链接,但是,每个级别的子文件夹将具有不同的路径,在以下结构中:

navlist1 = http://www.somewhere.com/here/ / landing.htm

navlist2&amp; 3 = http://www.somewhere.com/here/there/ / index.htm

文件夹是目录的实际文件夹名称,而不是文本文件中的名称,显然链接将不起作用。

上面粗体的行不应该在输出中。

谢谢。

3 个答案:

答案 0 :(得分:1)

迭代而不是递归,实际上并没有这样计划,但它似乎是一种有趣的方式。 它看起来有点乱,对不起。
b.t.w.我忍不住也做了一个看起来更干净的递归的 (少了代码;请参阅我的其他答案。)

#!/bin/bash

#preset variables, exec redirects everything to outputfile
ROOT="/data"
exec > "$ROOT/Menu-test.html"
MAXLEVEL="*/* */*/* */*/*/* */*/*/*/*"
LABEL="foldername.txt"
NAVLIST=1
LEVEL=2
LAST=1

#functions for indentation, definition and printing tags
LI="<LI><SPAN class=plus><P>-</P></SPAN><A class=''>"
Indent() { for (( i=1 ; i < LAST ; ++i )); do echo -n "        " ; done ;}
BUecho() { Indent ; echo "<UL class=navlist""$LEVEL"">"                 ;}
EUecho() { Indent ; echo "</UL>"                                        ;}
BLecho() { Indent ; echo -n "    " ; echo "$LI""$DIRNAME""</A>"         ;}
ELecho() { Indent ; echo -n "    " ; echo "</LI>"                       ;}

# Create first level items - these are static
cat<<EOH
<UL class=navlist1>
    <LI><SPAN class=plus><p>-</p></SPAN><A class=''>Level 1 products</A>
EOH

#go to root of tree, scan tree, drop folders without label,drop labels,sort
#and start reading the result line by line .... 
cd "$ROOT" ; for SCANDIRS in $MAXLEVEL; do echo "$SCANDIRS"; done |\
grep "$LABEL" |sed "s/$LABEL/\//g" |sort |\
while [ "$LAST" -gt "0" ]
do
    #read directory entry, count slashes as depth indicator, read label
    if read LINE
    then
        LEVEL=$( tr -dc '/' <<<"$LINE" | wc -m )
        read DIRNAME < "$LINE/$LABEL"
    else
        LINE="" ; LEVEL=0
    fi

    #code logic, assembling tags
    if    [ "$LEVEL" -gt "$LAST" ];   then (( ++LAST )); BUecho; BLecho
    elif  [ "$LEVEL" -eq "$LAST" ];   then  ELecho; BLecho
    else
        while [ "$LEVEL" -lt "$LAST" ]; do  ELecho; EUecho; (( --LAST ));
        done; [ "$LAST"  -gt "0"     ] && { ELecho; BLecho;}
    fi
done

答案 1 :(得分:1)

也是一个递归的(我无法抗拒,抱歉); - )

#!/bin/bash

#preset variables, exec redirects everything to outputfile
ROOT="/data"
LABEL="foldername.txt"
MAXDEPTH=5
DEPTH=0
HTTP="http://www.somewhere.com"
exec > "$ROOT/Menu-test.html"

#functions for indentation, definition and printing tags
LI="<LI><SPAN class=plus><P>+</P></SPAN>"
ULecho() { Dent ; echo "<UL class='navlist$DEPTH'>"                    ;}
LIecho() { echo -n "$LI<A href='$HTTP${1/$ROOT/}/'>$( cat $LABEL)</A>" ;}
Indent() { for (( i=1 ; i < DEPTH ; ++i )); do Dent; Dent; done ; Dent ;}
Dent()   { echo -n "    "                                              ;}
LIstrt() { Indent; LIecho "$( pwd )" ; echo "</LI>"                    ;}
ULstrt() { Indent; LIecho "$( pwd )" ; echo; Indent; ULecho            ;}
TAGend() { Indent ; Dent ; echo "</UL>"; Indent; echo "</LI>"          ;}
DEPchk() { [ "$DEPTH" -gt "0" ] && ${1} ;}

:> $ROOT/$LABEL

Dive()
{
    local DPATH="$1"


    if [ "$( echo */$LABEL )" = "*/$LABEL" ] || [ $DEPTH -gt $MAXDEPTH ]
    then
        DEPchk LIstrt
    else
        DEPchk ULstrt
        for DPATH in */$LABEL
        do
            cd ${DPATH%/*}
              (( ++DEPTH ))
            Dive "$DPATH"
              (( --DEPTH ))
            cd ..
        done
        DEPchk TAGend
    fi
}

cd $ROOT
Dive "$ROOT"
echo "</UL>"

更新:
我试图添加你提到的一些额外的东西,但我想我没有详细的想法。也许是因为我对HTML的了解几乎不存在。所以你真的必须为我拼出来; - )

答案 2 :(得分:0)

我使用这个脚本来生成一个 html 目录:

#!/bin/sh

# find ./ | grep -i "\.*$" >files
find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files
listing="files"

out=""

html="index.html"
out="basename $out.html"
html="index.html"
cmd() {

  echo '  <!DOCTYPE html>'
  echo '<html>'
  echo '<head>'

  echo '  <meta http-equiv="Content-Type" content="text/html">'

  echo '  <meta name="Author" content="Bryan Guner">'
  echo '<link rel="stylesheet" href="./assets/prism.css">'
  echo ' <link rel="stylesheet" href="./assets/style.css">'
  echo ' <script async defer src="./assets/prism.js"></script>'

  echo "  <title> directory </title>"

  echo ""
  echo '<style>'


echo '    a {'
echo '      color: black;'
echo '    }'
echo ''
echo '    li {'
echo '      border: 1px solid black !important;'
echo '      font-size: 20px;'
echo '      letter-spacing: 0px;'
echo '      font-weight: 700;'
echo '      line-height: 16px;'
echo '      text-decoration: none !important;'
echo '      text-transform: uppercase;'
echo '      background: #194ccdaf !important;'
echo '      color: black !important;'
echo '      border: none;'
echo '      cursor: pointer;'
echo '      justify-content: center;'
echo '      padding: 30px 60px;'
echo '      height: 48px;'
echo '      text-align: center;'
echo '      white-space: normal;'
echo '      border-radius: 10px;'
echo '      min-width: 45em;'
echo '      padding: 1.2em 1em 0;'
echo '      box-shadow: 0 0 5px;'
echo '      margin: 1em;'
echo '      display: grid;'
echo '      -webkit-border-radius: 10px;'
echo '      -moz-border-radius: 10px;'
echo '      -ms-border-radius: 10px;'
echo '      -o-border-radius: 10px;'
echo '    }'
echo '  </style>'
  echo '</head>'

  echo '<body>'

  echo ""

  # continue with the HTML stuff

  echo ""

  echo ""

  echo "<ul>"

  awk '{print "<li><a href=\""$1"\">",$1,"&nbsp;</a></li>"}' $listing

  # awk '{print "<li>"};

  #     {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing

  echo ""

  echo "</ul>"

  echo "</body>"

  echo "</html>"

}

cmd $listing --sort=extension >>$html



sudo sed -i '/\.git/d' ./index.html
sudo sed -i '/node_modules/d' ./index.html
sudo sed -i '/right\.html/d' ./index.html
sudo sed -i '/sol\~/d' ./right.html
sudo sed -i '/\.json/d' ./index.html
sudo sed -i '/\.gif/d' ./index.html
sudo sed -i '/\.png/d' ./index.html
sudo sed -i '/\.css/d' ./index.html
sudo sed -i '/\.js/d' ./index.html
sudo sed -i '/\.php/d' ./index.html
sudo sed -i '/\.md/d' ./index.html
sudo sed -i '/\.svg/d' ./index.html
sudo sed -i '/\.jpeg/d' ./index.html
sudo sed -i '/\.jpg/d' ./index.html
sudo sed -i '/\.scss/d' ./index.html
sudo sed -i '/scss/d' ./index.html
sudo sed -i '/\.txt/d' ./index.html
sudo sed -i '/\.ttf/d' ./index.html
sudo sed -i '/\.pdf/d' ./index.html
sudo sed -i '/\.mp4/d' ./index.html
sudo sed -i '/\.pug/d' ./index.html
sudo sed -i '/\.DS_store/d' ./index.html
sudo sed -i '/\.DS_Store/d' ./index.html
sudo sed -i '/\.sql/d' ./index.html
sudo sed -i '/\.py/d' ./index.html
sudo sed -i '/\.xlsx/d' ./index.html
sudo sed -i '/\.JPG/d' ./index.html
sudo sed -i '/\.TTF/d' ./index.html
sudo sed -i '/\.ttf/d' ./index.html
sudo sed -i '/\.eot/d' ./index.html
sudo sed -i '/\.ttc/d' ./index.html
sudo sed -i '/\.PNG/d' ./index.html
sudo sed -i '/\.java/d' ./index.html
sudo sed -i '/\.png/d' ./index.html
sudo sed -i '/\.jpeg/d' ./index.html
sudo sed -i '/\.gif/d' ./index.html
sudo sed -i '/\.go/d' ./index.html
sudo sed -i '/\.vue/d' ./index.html

结果是这样的目录页面:

website