res (01/25/83)
There have been several programs posted to the net to get a listing
of the structure of a directory system. The following shell also
generates a simple form of such a listing, without all the grand
and glorious information about access privileges, size, et al.
I have called it catalog ... since it is recursive you should
name it likewise, or change the recursive invocation. The instructions
are reasonably complete.
# catalog - produce complete file structure list from directory
#
# Parameters: 1: directory name (optional)
# 2: indentation string (empty on first call)
#
# Produces on standard output the file structure emanating from
# the current directory. Each descent into a subdirectory
# is indicated by further indentation. Directories are indicated
# by surrounding [], and executable files are prefaced with a *.
#
if [ "$1" = "" ]
then
echo "file structure from directory `pwd`"
date
echo "\n\n"
fi
if [ "$1" != "" ]
then
cd $1
fi
for i in *
do
if test -d $i
then
echo "${2}[ $i ]"
catalog $i "$2 . "
else
if [ "$i" != '*' ]
then
if test -x $i
then
echo "${2} *$i "
else
echo "${2} $i "
fi
fi
fi
done
Some sample output follows:
file structure from directory /n1/res/bin
Tue Jan 25 12:49:44 CST 1983
*fort
fortdata
*sh
[ source ]
. fort.c
. sh.c
. soxpnd.c
*soxpnd
temp nyuada (01/28/83)
Would someone please explain to me why everbody is writing shell scripts
that do recursive directory listings? How are they significantly better
than "ls -R"? If you want to do more general things than list files, but
do it recursively to a directory tree, you can use "find". It's syntax
is a little odd and its semantics are kludgy so I wrote a csh script that
executes an arbitrary one-line csh command repeatedly (and, optionally,
recursively) on a list of files/directories. It follows, beginning with
a comment containing the documentation. Hope this is useful to some of
you.
#
# Loop on files
#
# Synopsis:
# loopf [-R[ad]] cmd file...
#
# Executes cmd once for each file, arranging that $1 will be set to the file
# name during execution of cmd. $2, $3, ... will be set to the remaining
# (unprocessed) args. If no files are given, "." is used. If there are no
# occurrences of $ in the cmd, " $1" is appended to it causing the cmd to be
# executed with each file as a single parameter. If -R is set, the cmd is not
# executed on directory files, but the names of such directories are printed
# and they are recursively processed. With -Rd, the cmd is executed on direc-
# tories instead of printing them, then they are recursively processed. With
# -Ra or -Rad, files beginning with . (except . and ..) are processed also, but
# note that "loopf -Ra cmd *" will not process such files in the current direc-
# tory, because the * is expanded before loopf is invoked (use "loopf -Ra cmd
# ."). All cmd executions (at same recursive level) get executed in a single
# csh process. Hence csh variables may be set and tested usefully. Also, to
# control execution, break, exit and continue may be used within the cmd.
#
# Examples:
# loopf 'od -X' * /* prints hex dump of all
# /* files in current dir */
# loopf 'cp $1 $1.back' a b /* causes: cp a a.back */
# /* cp b b.back */
# loopf 'echo $#argv ; break' * /* prints # files in dir */
# loopf 'if ($2 != "") mv $2 $1' tmp a b tmp
# /* swaps files a and b */
# loopf -R 'if ($1 =~ *.c) ls -l $1' / /* lists all .c files */
# loopf -Rd\
# 'echo $1; if (-d $1) mkdir dest/$1 ; if (! -d $1) cp $1 dest/$1' *
# /* recursively copies current
# dir to dest dir, making any
# neccessary subdirs. */
# loopf \
# 'if (! $?sum) @ sum=0 ; @ sum = $sum + $1 ; if ($2 == "") echo $sum' \
# $vector /* prints +/vector (plus */
# /* reduction of $vector) */
#
set nonomatch
set recurse = "false"
set dodirs = "false"
set dodots = "false"
if ("$1" =~ -R*) then
# echo "Recursive loop"
set switch = "$1"
set recurse = "true"
if ("$1" =~ -R*d*) then
set dodirs = "true"
endif
if ("$1" =~ -R*a*) then
set dodots = "true"
endif
shift
endif
if ($#argv == 0) then
echo "Usage: loopf [-R[ad]] cmd file..."
exit
else if ($#argv == 1) then
set argv = ("$argv[1]" ".")
endif
if ("$1" =~ *\$*) then
set cmdarg = "$1"
else
set cmdarg = "$1"' $1'
endif
alias cmd 'set argv=(\!*) ; '"$cmdarg"
set files = ($argv[2-]:q)
set needblnk = "false"
while ($#files > 0)
if ($recurse == "true" && -d $files[1]) then
if ($dodots == "true") then
set dircnts = ( {${files[1]}/.[0-z],${files[1]}/}* )
else
set dircnts = ( ${files[1]}/* )
endif
if ("$dircnts" =~ *\*) set dircnts = ()
if ($dodirs == "true") then
cmd $files
else
if ($needblnk == "true") echo " "
echo "${files[1]}:"
endif
if ($#dircnts > 0) then
loopf "$switch" "$cmdarg" $dircnts:q
if ($dodirs == "false") echo " "
set needblnk = "false"
endif
else
cmd $files
set needblnk = "true"
endif
shift files
end