Need to simplify a script that makes cool trees

Kristian Vaaf vaaf at broadpark.no
Sat Jan 7 10:14:45 PST 2006


Hello!

This script produces a real sweet file and directory tree.

I am trying to simplify this -- it is too big for its own good.

I must remove all the bullshit but the -a switch.

And I'm sure the same thing could be accomplished in just a few lines.

Here is what it does:

# fs-tree
#
/usr/home/vaaf/mp3/out
+-----benny_benassi-whos_your_daddy-promo-cdm-2005-nbd
+-----bugz_in_the_attic-booty_la_la-mystery_and_matt_early_remix-vinyl-2005-mtc
+-----chris_cox-live_from_park_pavilion_atlanta-sat-01-01-2006-hsalive

# fs-tree -a
#
/usr/home/vaaf/mp3/out
+-----benny_benassi-whos_your_daddy-promo-cdm-2005-nbd
|     +-----00-benny_benassi-whos_your_daddy-promo-cdm-2005-nbd.m3u
|     +-----00-benny_benassi-whos_your_daddy-promo-cdm-2005-nbd.nfo
|     +-----00-benny_benassi-whos_your_daddy-promo-cdm-2005-nbd.sfv

And so forth.

Here is the original script:

#!/bin/sh
#
#   Read a directory or file list,then write a tree.
#   $URBAN: fs-tree.sh,v 1.0 2005/10/24 15:05:09 vaaf Exp $
#
#   -a, --all       Prints all files, not just directories.
#   -h, --help      Prints usage information.
#   -l, --list      Reads a list of files from stdin.
#   -v, --version   Print the version and exit.
#

PATH=/bin:/usr/sbin:/usr/bin:/usr/local/bin

export PATH
umask 022

tag=`basename $0`

# *** Functions
#
#     die: prints an optional argument to stderr and exits.
#     warn: prints an optional argument to stderr.
#
#     A common use for "die" is with a test:
#
#     test -f /etc/passwd || die "No password file."
#
#     This works in subshells and loops,
#     but may not exit with a code other than 0.
#
die () {

	echo "$tag: Error: $*" 1>&2
	exit 1

}

# *** Usage
#
#     Prints an optional string plus part of the comment header
#     (if any) to stderr, and exits with code 1.
#
usage () {

	lines=`egrep -n '^# (NAME|AUTHOR)' $0 | sed -e 's/:.*//'`

	(

		case "$#"

		in
			0) ;;
			*) echo "Usage error: $*"; echo ;;
		esac

		case "$lines"

		in
			"") ;;
			*) set `echo $lines | sed -e 's/ /,/'`
				sed -n ${1}p $0 | sed -e 's/^#//g' |
				egrep -v AUTHOR:
			;;

		esac ) 1>&2

	exit 1

}

# *** Version
#
#     Prints the current version to stdout.
#
version () {

	lsedscr='s/RCSfile: //
	s/.Date: //
	s/,v . .Revision: /  v/
	s/\$//g'

	lrevno='$RCSfile: fs-tree.sh,v $ $Revision: 1.0 $'
	lrevdate='$Date: 2005/09/09 01:17:30 $'
	echo "$lrevno $lrevdate" | sed -e "$lsedscr"
	exit 0

}

# *** mktree
#
#     Sort the file information properly.
#
mktree () {

	scr='
	s,^.$,,
	/^$/d
	s,[^/]*/\([^/]*\)$,+-----\1,
	s,[^/]*/,|     ,g'

	tr '/' '\001' | sort -f | tr '\001' '/' | sed -e "$scr"

}

# *** Main program defaults
#
ac_help=
ac_prev=
ac_invalid="Invalid option; use --help to show usage"
argv=

# *** Initialize some variables set by options.
#
all=no
list=no
fopt="-type d"

for ac_option; do

	# *** If the previous option needs an argument, assign it.
	#
	case "$ac_prev" in

		"") ;;
		*) eval "$ac_prev=\$ac_option"; ac_prev=; continue ;;

	esac

	case "$ac_option" in

		-*=*) ac_optarg=`echo "$ac_option" |
			sed 's/[-_a-zA-Z0-9]*=//'` ;;
		*) ac_optarg= ;;

    esac

    # *** Main switch
    #
	case "$ac_option" in

		-a | -all | --all | --al | --a)
			all=yes; fopt="" ;;

		-h | -help | --help | --hel | --he)
			usage ;;

		-l | -list | --list | --lis | --li | --l)
			list=yes ;;

		-v | -version | --version | --versio | --versi | --vers)
			version ;;

		-*) die "$ac_option: $ac_invalid" ;;
		*) argv="$argv $ac_option" ;;

	esac

done

case "$ac_prev" in

	"") ;;
	*) die "Missing argument to --`echo $ac_prev | sed 's/_/-/g'`" ;;

esac

# *** Real work starts here.
#     Test for specific features.
#
case "$argv"

in

	"") case "$list" in
			"yes") top="" ;; # Sort reads stdin.
			*) top="." ;;

		esac
		;;

	*) top=$argv ;;

esac

# *** Print the directory tree.
#
case "$list"

in

	"no") test -d $top || die "$top: not a directory"
		cd $top; pwd; find . $fopt -print | mktree ;;

	"yes") mktree < $top ;;

esac

exit 0

--

And here is my attempt to simplify it.
Now, mind you that this doesn't even work!

#!/bin/sh
#
#   Read a directory or file list, then write a tree.
#   $URBAN: fs-tree.sh,v 1.0 2005/10/24 15:05:09 vaaf Exp $
#
#   Print files in addition to directories: -a
#

tree() {

	do=`tr '/' '\001' | sort -f | tr '\001' '/' |

	sed -e 's,^.$,,' \
		-e '/^$/d' \
		-e 's,[^/]*/\([^/]*\)$,+-----\1,' \
		-e 's,[^/]*/,|     ,g'`

}

all="-type d"

while [ $# -gt 0 ]; do

	case $1 in

		-a) all="" ;;
	
	esac
        
	shift

done

find . $dir $all | tree

--

I'm the biggest rookie you've ever seen.
But I'm thinking this still looks too advanced for its purpose.

Any suggestions?

Thanks!



More information about the freebsd-questions mailing list