创建HTML导航菜单的bash脚本

创建HTML导航菜单的bash脚本,bash,Bash,不久前,我编写了一个javascript程序来循环遍历目录树,并从树的前3个级别构建一个html nav菜单文件。我现在正试图用bash来复制它,因为JS程序需要IE浏览器和activeX来运行。我对bash相当陌生,因此这对我来说是一次很好的学习经历 因此,我的结构如下: -Folder A --Folder B --Folder C --Folder C1 --Folder C2 --Folder CC1

不久前,我编写了一个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;
#/bin/bash
ROOT=/data/
OUTPUTFILE=${ROOT}/Menu-test.html
#创建第一级项目-这些是静态的
HEADING=“
因此,这是当前的工作输出。我还需要做的是在每个文件夹中包含href链接,但是,每个级别的子文件夹都有不同的路径,如下所示:

navlist1=/landing.htm

navlist2&3=/index.htm

folder是目录的实际文件夹名称,而不是文本文件中的名称,否则链接显然无法工作

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


谢谢。

迭代而不是递归,这实际上并不是计划好的,但似乎是一种有趣的方法。 看起来有点乱,很抱歉。
b、 t.w.我忍不住还要做一个递归的,看起来更干净
(代码更少;请参阅我的其他答案。)

!/bin/bash
#预设变量,exec将所有内容重定向到outputfile
ROOT=“/data”
exec>“$ROOT/Menu test.html”
MAXLEVEL=“*/***/***/***/***/***/***/*/*/*/*”
LABEL=“foldername.txt”
导航列表=1
级别=2
最后=1
#缩进、定义和打印标签的功能
LI=“
  • -

    ” Indent(){for((i=1;i”;} EUecho(){Indent;echo“”;} BLecho(){Indent;echo-n”“;echo“$LI”“$DIRNAME”“;} ELecho(){Indent;echo-n”“;echo“
  • ”;} #创建第一级项目-这些是静态的 cat也是一个递归的(对不起,我无法抗拒);-)

    !/bin/bash
    #预设变量,exec将所有内容重定向到outputfile
    ROOT=“/data”
    LABEL=“foldername.txt”
    最大深度=5
    深度=0
    HTTP=”http://www.somewhere.com"
    exec>“$ROOT/Menu test.html”
    #缩进、定义和打印标签的功能
    LI=“
  • +

    ” ULecho(){Dent;echo“”;Indent;echo“
  • ”;} DEPchk(){[“$DEPTH”-gt“0”]&&${1};} :>$ROOT/$LABEL 潜水 { 本地DPATH=“$1” 如果[“$(echo*/$LABEL)”=“*/$LABEL”]| |[$DEPTH-gt$MAXDEPTH] 然后 德普切克利斯特尔特 其他的 德切克超低硫柴油机 对于*/$LABEL中的DPATH 做 cd${DPATH%/*} ((++深度)) 潜水“$DPATH” (((-深度)) 光盘 完成 德普切克塔根 fi } cd$ROOT 潜水“$ROOT” 回声“”
    更新:

    我试图添加一些您也提到过的额外内容,但我想我对它没有详细的了解。可能是因为我对HTML的了解几乎不存在。因此您必须为我详细说明;-)

    我没有包含-maxdepth的find版本。不幸的是。
    **<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>**
    
    #!/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>"