bash script to create a HTML nav menu
bash
Solution
Also a recursive one (I couldn't resist, sorry) ;-)
#!/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>"
UPDATE: I tried to add some of the extra's you also mentioned but I think I do not have a detailed vision of it. Maybe because my knowledge of HTML is almost non-existent. So you really have to spell it out for me ;-)
Problem
A while ago I wrote a javascript program to loop through a directory tree and build a html nav menu file from the first 3 levels of the tree. I now am trying to replicate this using bash, as the JS program requires the IE browser and activeX to run. I am reasonably new to bash, so this is a great learning experience for me. So, what I have is a structure as follows: ``` -Folder A --Folder B --Folder C --Folder C1 --Folder C2 --Folder CC1 --Folder D --Folder D1 --Folder E ``` etc. You get the point. Anyway, the folder names vary, but each folder has a single text file in it called "foldername.txt". In this file is a single line of text that has the actual folder name to be used on the menu (this is due to the length of some of the names). I am therefore trying to loop through each folder/subfolder down to level 3 only, read each foldername.txt file in the folder and return the name, whilst maintaining the folder heirarchy. I hope that makes sense. The output is appended with html tags and echoed to a .htm file. So far I have tried different things. The code below almost does what I want, it will scan directories and return the names as per the text file, but does not maintain heirarchy. I do not have a version of find that includes -maxdepth unfortunately. As you can see, I've tried nested loops as it's only 3 deep, but the recursion continues for each level so that I get duplicate and odd results. ``` #!/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; ``` Sorry for the long post and messy code, but I really wanted to try doing this myself first as this is how I learn best. So any ideas on how I could get this to work. Please note that I do not have access to Python or any other language, so bash it is. The output I'm looking for would something like as follows (hyphens are only to maintain formatting and are not in the output): ``` **<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>** ``` So, this is the current working output. What I also need to do is include the href link in each of the , however, each level of subfolder will have a different path, in the following structure: navlist1 = http://www.somewhere.com/here//landing.htm navlist2 & 3 = http://www.somewhere.com/here/there//index.htm folder is the actual folder name of the directory, not the name in the text file, obviously the link won't work otherwise. The lines in bold above should not be in the output. Thank you.