繁体   English   中英

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

[英]bash script to create a HTML nav menu

前段时间我写了一个javascript程序来遍历目录树,并从树的前3个级别构建一个html导航菜单文件。 我现在正在尝试使用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或任何其他语言,所以bash它是。

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

**<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&3 = http://www.somewhere.com/here/there/ /index.htm

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

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

谢谢。

迭代而不是递归,实际上没有计划,但它似乎是一个有趣的方式来做到这一点。 它看起来有点乱,对不起。
顺便说一下,我也忍不住做一个看起来更干净的递归
(和更少的代码;见我的其他答案。)

#!/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

也是一个递归的(我无法抗拒,对不起);-)

#!/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的了解几乎不存在。 所以你真的要拼出来给我;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM