#! /bin/bash
help=\
"Syntax: vtree [startdir] [namelen=#] [linelen=#]
If startdir is not specified, tree will start at current dir.
namelen specifies the minimum number of characters of a directory name that
are guaranteed to be printed.
This is a tradeoff between the number of tree levels that can fit on a
screen line and the number of chars of each dir name that can be printed.
In most cases it will be possible to print more than namelen characters of
the name (a name up to namelen+1 chars will always be printed in full),
but in some cases truncation down to namelen chars will occur.
If truncation occurs, a '>' is printed at the end of the name.
namelen=8 (the default) typically causes about 5 dirs/1000 to be truncated.
namelen=7 typically causes about 10 dirs/1000 to be truncated.
namelen=8 will allow 6 full length dirs to be printed in 79 columns.
namelen=7 will allow 7 full length dirs to be printed in 79 columns;
linelen specifies the maximum number of characters to print on one screen
line. All characters beyond this are truncated. The default is 1024.
To avoid line wrap on an 80 column terminal with autowrap, use linelen=79.
"
for i in "$@"; do
case $i in
-h) echo "$help"; exit;;
*=*)
vars="$vars $i"
;;
*)
if [ ! -x $i ] || [ ! -d $i ]; then echo "$i: directory not accessible."
exit
fi
cd $i
;;
esac
shift
done
pwd
find . -type d -print 2> /dev/null | \
gawk -F/ '
NR == 1 {
if (namelen)
MaxLen = namelen;
else
MaxLen = 8;
if (!linelen)
linelen = 1024
HSpace = substr(" ",1,MaxLen); n = 0; }
$0 != "." { if (NF == 2 && n > 0) list();
Depth[n] = NF - 1; Name[n++] = $NF;
}
END {
list() }
function list() {
Line = Name[0]; for (i = 1; i < n; i++) { if (Depth[i] == Depth[i-1] + 1)
AddHLink(); else {
print substr(Line,1,linelen); Line = ""; for (d = 1; d < Depth[i] - 1; d++) if (VLink[d])
Line = Line HSpace " | ";
else Line = Line HSpace " ";
if (VLink[d] == i) {
VLink[d] = 0; Line = Line HSpace " \\--";
}
else
Line = Line HSpace " |--";
}
Line = Line Name[i]; }
print substr(Line,1,linelen); n = 0; }
function AddHLink() {
NDepth = Depth[i]; VLink[NDepth - 1] = 0;
for (j = i + 1; j < n && Depth[j] >= NDepth; j++)
if (Depth[j] == NDepth)
VLink[NDepth - 1] = j;
if (VLink[NDepth - 1]) {
NLine = substr(Line,1,(NDepth - 2) * (MaxLen + 4) + MaxLen + 1);
if (length(NLine) < length(Line))
Line = substr(NLine,1,length(NLine) - 1) ">"
else
Line = NLine;
Line = Line substr("--------------+--",
18 - ((NDepth - 1) * (MaxLen + 4) - length(Line)));
}
else {
NLine = substr(Line,1,(NDepth - 2) * (MaxLen + 4) + MaxLen + 3);
if (length(NLine) < length(Line))
Line = substr(NLine,1,length(NLine) - 1) ">"
else
Line = NLine;
Line = Line substr("-----------------",
1,(NDepth - 1) * (MaxLen + 4) - length(Line));
}
}
' $vars