georgeb@fai.UUCP (George Bosworth) (08/01/90)
I'm looking for a Unix version of the DOS "tree" command, that makes a hierarchal list of subdirectories. Not hard to write, of course, but hoping not to spend the time. Thanks for source or pointer to same, by email. George Bosworth uunet!fai.com!georgeb Fujitsu America, Inc.
bruceb@telesoft.com (Bruce Bergman @quasar) (08/02/90)
In article <2899@fai.UUCP>, georgeb@fai.UUCP (George Bosworth) writes: > I'm looking for a Unix version of the DOS "tree" command, > > George Bosworth uunet!fai.com!georgeb Here's the puppy. It's not great, but it does the trick. It's intended for BSD. Just do a "cc -o tree tree.c" and you'll be set. Have fun! bruce ----- cut here ----- #include <stdio.h> #include <sys/types.h> #include <sys/dir.h> #include <sys/stat.h> #include <sys/param.h> #define TRUE 1 #define FALSE !TRUE int display_files = FALSE; /* * * Tree.c -- Mimic the DOS tree command * * By Bruce A. Bergman, 8767 Dalewood Avenue, San Diego, CA. 92123-3926 * bruceb@telesoft.com (619) 457-2700 x123 * * Modification History * * Who What Where * --- --------- ----- * bab 18-Jan-88 Initial creation. * * Released into the public domain as long as authorship remains intact. * */ main(argc, argv) int argc; char *argv[]; { char path[MAXNAMLEN+1]; if (argc <= 2) { if (argc == 2) { if (strncmp(argv[1], "-f", 2) == 0) { display_files = TRUE; start_at(getwd(path)); } else { start_at(argv[1]); } } else { start_at(getwd(path)); } } else { while (--argc > 0) { ++argv; if (strncmp(*argv, "-f", 2) == 0) { display_files = TRUE; continue; } strcpy(path, *argv); start_at(path); display_files = FALSE; if (argc > 1) { printf("\n"); } } } } start_at(path) char *path; { DIR *fd; if ((fd = opendir(path)) == NULL) { fprintf(stderr, "%s is not a directory\n", path); return; } report(path, fd); closedir(fd); } traverse(base, dir) char *base, *dir; { DIR *fd; char *p; int b_len, d_len; if ((strcmp(dir, ".") == 0) || (strcmp(dir, "..") == 0)) { return; } b_len = strlen(base); d_len = strlen(dir); if ((p = (char *)malloc(b_len+d_len+2)) == 0) { fprintf(stderr, "malloc failure in traverse\n"); exit(0); } strcpy(p, base); *(p+b_len) = '/'; strcpy(p+b_len+1, dir); *(p+b_len+d_len+1) = '\0'; if ((fd = opendir(p)) != NULL) { report(p, fd); closedir(fd); } } report(path, fd) char *path; DIR *fd; { struct direct *buf; struct stat sbuf; char *p; int len, got_one; len = strlen(path); if ((p = (char *)malloc(len+MAXNAMLEN+2)) == 0) { fprintf(stderr, "malloc failure in report\n"); exit(0); } strcpy(p, path); *(p+len) = '/'; printf("Path: %s\n", path); printf("Sub-directories: "); got_one = FALSE; while ((buf = readdir(fd)) != NULL) { buf->d_name[buf->d_namlen] = '\0'; if ((strcmp(buf->d_name, ".") == 0) || (strcmp(buf->d_name, "..") == 0)) { continue; } strcpy(p+len+1, buf->d_name); if (stat(p, &sbuf) == -1) { continue; } if ((sbuf.st_mode & S_IFMT) == S_IFDIR) { if (got_one == FALSE) { got_one = TRUE; printf("%s\n", buf->d_name); } else { printf(" %s\n", buf->d_name); } } } if (got_one == FALSE) { printf("None\n"); } if (display_files == TRUE) { printf("Files: "); got_one = FALSE; rewinddir(fd); while ((buf = readdir(fd)) != NULL) { buf->d_name[buf->d_namlen] = '\0'; if ((strcmp(buf->d_name, ".") == 0) || (strcmp(buf->d_name, "..") == 0)) { continue; } strcpy(p+len+1, buf->d_name); if (stat(p, &sbuf) == -1) { continue; } if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { if (got_one == FALSE) { got_one = TRUE; printf("%s\n", buf->d_name); } else { printf(" %s\n", buf->d_name); } } } if (got_one == FALSE) { printf("None\n"); } } printf("\n"); rewinddir(fd); while ((buf = readdir(fd)) != NULL) { buf->d_name[buf->d_namlen] = '\0'; traverse(path, buf->d_name); } } ----- cut here ----- -- att! \ crash!--\ TeleSoft (bruceb@telesoft.com) ncr-sd! \ \ 5959 Cornerstone Court West >--ucsd!---->--telesoft!bruceb (Bruce Bergman N7HAW) nosc! / / San Diego, CA. 92121-9891 ucbvax!/ uunet!--/ (619) 457-2700 x123 All opinions are my own. Have you hugged your horse lately?
georgeb@fai.UUCP (George Bosworth) (08/11/90)
In article <2899.UUCP> I asked for a UNIX version of the DOS "tree" command. Many responders didn't know, or had forgot, that the DOS "tree" command produces an INDENTED subdirectory tabulation, wherein each deeper level of subdirectory is indented further to the right, to give instant visualization of the hierarchy. The frequently-suggested UNIX commands *find*, *ls -R*, and *du* produce only columnar ouput. Several responders sent C programs or shell scripts that did some flavor of indented hierarchal directory tabulation, or offered or pointed to programs or scripts, including lengthy C programs available by UUCP as uunet!/usr/spool/ftp/comp.sources.misc/volume9/dtree.Z and uunet!/usr/spool/ftp/comp.sources.unix/volume15/vtree.Z. One respnder sent a uvtree2 Bourne shell script that was published by Ray Swartz in the June 1989 Unix Review. It worked well. Following this up, I saw a dtree Bourne shell script published by Ray in the October issue. It works well and is extremely compact: : # @(#) dtree -- Visual display of directory trees # Author: Unknown USAGE="Usage: $0 [starting-directory-name]" case $# in 0) startdir="." ;; #If no param, start at dot 1) if [ ! -d $1 ]; then #Single param; directory? echo "\"$1\" not a directory." >&2 echo $USAGE >&2 exit 1 fi startdir=$1 ;; #Use single param as start *) echo $USAGE >&2 #Multiple params exit 2 ;; esac (cd $startdir; pwd) #In subshell, print start name find $startdir -type d -print | sort -f | #Find, sort names sed -e "s,^$startdir,," \ -e "/^$/d" \ -e "s,[^/]*/\([^/]*\)$,\|----\1," \ -e "s,[^/]*/,| ,g" Here is a sample run: pwd /fai/ddd/georgeb dtree /fai/ddd/georgeb |----Keep |----News |----Present | |----Big | | |----Filed | | |----Working | |----Small |----Pthread |----Recruit |----Uunet George Bosworth georgeb@fai.com Fujitsu America Inc. uunet!fai.com!georgeb