前段时间我写了一个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'>•</p></SPAN><A href='http://www.somewhere.com/index.htm'>Folder A1</A></LI>
<LI><SPAN class='bull'><p class='bull'>•</p></SPAN><A href='http://www.somewhere.com/index.htm'>Folder A2</A></LI>
<LI><SPAN class='bull'><p class='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
文件夹是目录的实际文件夹名称,而不是文本文件中的名称,显然链接将不起作用。
上面粗体的行不应该在输出中。
谢谢。
答案 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)
#!/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," </a></li>"}' $listing
# awk '{print "<li>"};
# {print " <a href=\""$1"\">",$1,"</a></li> "}' \ $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