olasov@cs.columbia.edu (Benjamin Olasov) (05/20/89)
I'm interested in finding a unix command usage that will return the complete path names of all subdirectories below a given directory, so that, given a directory tree like this: |----- /user1 | / | /sys -- |----- /user2 ----- /data ----- /bin / \ | / | / |----- /user3 ----- /docs /files ----- /home ----- /users --| \ | \ |----- /user4 \ | /vol | |----- /user5 | | |----- /user6 ----- /mail \ \ \ /hacks the command would take the directory of interest as its argument, as in: $ mycommand /files/home/users and return the subdirectories in the format: /files/home/users/user1 /files/home/users/user2 /files/home/users/user2/data /files/home/users/user2/data/bin /files/home/users/user3 /files/home/users/user3/docs /files/home/users/user4 /files/home/users/user5 /files/home/users/user6 /files/home/users/user6/mail /files/home/users/user6/hacks What's the easiest way to do this? Ben
mani@csun1.UUCP (Maninder Chawla) (05/21/89)
From article <215@cs.columbia.edu>, by olasov@cs.columbia.edu (Benjamin Olasov): > > > I'm interested in finding a unix command usage that will return the complete > path names of all subdirectories below a given directory, so that, given a /* stuff deleted */ I am sure there are lots of ways to do this. Here's a recursive C program to do it. It has its own limitations like maximum path length. I have a tree printing version of it too. It uses curses, terminfo etc. The listing for syserr.h is also included. --mani mani@csun1.cs.uga.edu mani%csun1.cs.uga.edu@gatech.edu _____________________________________________________________________________ # include <string.h> # include <stdio.h> # include <sys/types.h> # include <sys/dir.h> # include <sys/stat.h> # include <"syserr.h"> char *path, *pname; int cnt; main() { path=(char *)malloc(100); pname=(char *)malloc(100); strcpy(path,".");cnt = 0; workout(); } workout() { struct stat *sbuf; struct direct *dlink; int nread; char *dname, *temp; DIR *dirp; sbuf=(struct stat *)malloc(sizeof(struct stat)); dlink=(struct direct *)malloc(sizeof(struct direct)); dname=(char *)malloc(20); if ((dirp=opendir(path)) == NULL ) syserr("open root"); while ((dlink=readdir(dirp)) != NULL) { if ( !dlink->d_ino ) continue; strcpy(dname,dlink->d_name); if (!strcmp(dname,".") || !strcmp(dname,"..")) continue; strcpy(pname,path);strcat(pname,"/");strcat(pname,dname); if (stat(pname, sbuf)== -1) syserr("stat"); if (((sbuf->st_mode) & S_IFMT) != S_IFDIR) continue; printf("%d %s is a directory. Path is %s\n",cnt++,dname,pname); strcat(path,"/"); strcat(path, dname); workout(); } closedir(dirp); if ((temp=strrchr(path,'/'))!=NULL) *temp = '\0'; } /* end of program */ _________________________________________________________________________ syserr.h listing # include <stdio.h> syserr(msg) /* print system call error message & quit */ char *msg; { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr, "ERROR: %s (%d", msg, errno); if (errno > 0 && errno < sys_nerr ) fprintf(stderr,";%s)\n", sys_errlist[errno]); else fprintf(stderr,")\n"); exit(1); }
charlie@mica.stat.washington.edu (Charlie Geyer) (05/21/89)
In article <215@cs.columbia.edu> olasov@cs.columbia.edu (Ben Olasov) writes: >I'm interested in finding a unix command usage that will return the complete >path names of all subdirectories below a given directory find directoryname -type d -print
wcf@psuhcx.psu.edu (Bill Fenner) (05/21/89)
In article <215@cs.columbia.edu> olasov@cs.columbia.edu (Ben Olasov) writes: |I'm interested in finding a unix command usage that will return the complete |path names of all subdirectories below a given directory find /files/home/users -type d -print Bill -- Bitnet: wcf@psuhcx.bitnet Bill Fenner | "Yesterday starts Internet: wcf@hcx.psu.edu | tomorrow; tomorrow UUCP: {gatech,rutgers}!psuvax1!psuhcx!wcf | starts today" Fido: Sysop at 1:129/87 (814/238 9633) \hogbbs!wcf | -- Marillion
bzs@bu-cs.BU.EDU (Barry Shein) (05/21/89)
>What's the easiest way to do this? > >Ben find dirname -print -- -Barry Shein, Software Tool & Die There's nothing more terrifying to hardware vendors than satisfied customers.
wlm@archet.UUCP (William L. Moran Jr.) (05/22/89)
In article <215@cs.columbia.edu> olasov@cs.columbia.edu (Ben Olasov) writes: > > >I'm interested in finding a unix command usage that will return the complete >path names of all subdirectories below a given directory, so that, given a >directory tree like this: ... deleted >What's the easiest way to do this? Why not simply use find /foo -type d -print ? Unless I misunderstand what you are trying to do, this does it. It'll produce stuff like: /foo/bar /foo/baz /foo/baz/beep Bill Moran -- arpa: moran-william@cs.yale.edu or wlm@ibm.com uucp: uunet!bywater!acheron!archet!wlm or decvax!yale!moran-william ------------------------------------------------------------------------------- To keep on running, try with all our might, But in the midst of effort faint and fail;
rbj@dsys.icst.nbs.gov (Root Boy Jim) (05/23/89)
? In article <215@cs.columbia.edu> olasov@cs.columbia.edu (Ben Olasov) writes:
? |I'm interested in finding a unix command usage that will return the complete
? |path names of all subdirectories below a given directory
? find /files/home/users -type d -print
Almost. Don't forget to pipe it to `sort', as find doesn't.
And BZS forgot that he asked for directorys only.
One thing I recently discovered is that find takes multiple directorys
before the options: find /here /there /everywhere -dothis -dothat ...
Root Boy Jim is what I am
Are you what you are or what?
guy@auspex.auspex.com (Guy Harris) (05/23/89)
>I am sure there are lots of ways to do this. Here's a recursive C program to >do it. Yes, there are lots of ways; using the already-written "find" command is far easier than writing your own program to do the same thing....
spl@mcnc.org (Steve Lamont) (05/23/89)
In article <19707@adm.BRL.MIL> rbj@dsys.icst.nbs.gov (Root Boy Jim) writes: >? In article <215@cs.columbia.edu> olasov@cs.columbia.edu (Ben Olasov) writes: >? |I'm interested in finding a unix command usage that will return the complete >? |path names of all subdirectories below a given directory > >? find /files/home/users -type d -print > >Almost. Don't forget to pipe it to `sort', as find doesn't. .... Um... am I missing something or doesn't du -a . or du -a your_favorite_directory do all this good stuff without the fuss and muss? Is this really a "wizards" type question? -- spl Steve Lamont, sciViGuy EMail: spl@ncsc.org North Carolina Supercomputing Center Phone: (919) 248-1120 Box 12732/RTP, NC 27709
ray3rd@ssc-vax.UUCP (Ray E. Saddler III) (05/23/89)
In article <215@cs.columbia.edu>, olasov@cs.columbia.edu (Benjamin Olasov) asks: > > I'm interested in finding a unix command usage that will return the complete > path names of all subdirectories below a given directory, so that, given a > directory tree like this: > > ( Example deleted ) > > the command would take the directory of interest as its argument, as in: > > $ mycommand /files/home/users > > and return the subdirectories in the format: > > /files/home/users/user1 > /files/home/users/user2 > /files/home/users/user2/data > /files/home/users/user2/data/bin > /files/home/users/user3 > /files/home/users/user3/docs > /files/home/users/user4 > /files/home/users/user5 > /files/home/users/user6 > /files/home/users/user6/mail > /files/home/users/user6/hacks > > What's the easiest way to do this? > Give this script a spin around the block: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #!/bin/sh # if [ $# = 0 ] then echo "Usage: mycommand <dir>" # # You could ask for the directory here, or assume a # default, if you so desired...I opt to exit non-zero # exit 1 else for I in $* do find $I -type d -exec ls -d {} \; done fi exit 0 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Sample usages: $ mycommand Usage: mycommand <dir> $ $ mycommand /user4/ray3rd /user4/law /user4/jsk /user4/markb /user4/ray3rd /user4/ray3rd/SYTEK /user4/ray3rd/HUMOR /user4/ray3rd/bin /user4/ray3rd/clock /user4/ray3rd/VTREE /user4/ray3rd/3B1 /user4/ray3rd/block /user4/ray3rd/CADSA /user4/ray3rd/UUMAP /user4/ray3rd/shartest /user4/ray3rd/STANDARDS /user4/law /user4/jsk /user4/markb $ $ mycommand . . ./SYTEK ./HUMOR ./bin ./clock ./VTREE ./3B1 ./block ./CADSA ./UUMAP ./shartest ./STANDARDS $ -- Ray E. Saddler III | __ __ __ __ | UseNet Boeing Aerospace | / / / // //| // | uw-beaver!ssc-vax!ray3rd P.O. Box 3999 m.s. 3R-05 | /-< / //- // |// _ | PhoneNet Seattle, Wa. 98124 USA | /__//_//__ // //__/ | 1+206-657-2824
jik@athena.mit.edu (Jonathan I. Kamens) (05/24/89)
\begin{Hugeflame} OK, folks, once again it's time to review briefly what newsgroup we're in right now, and what other newsgroups are available under the comp.unix heirarchy. This is COMP.UNIX.WIZARDS. The word "wizards" at the end is supposed to imply that the questions and discussions conducted herein require some GREATER THAN MINIMAL level of KNOWLEDGE and EXPERIENCE with the Unix operating system, in whatever variety, on the part of the people asking or discussing. It is my firmly held opinion that the following two topics DO NOT qualify as questions worthy of the comp.unix.wizards newsgroup: 1. "How do I delete a filename that has strange characters in it?" 2. "How to I print out the complete path names of all subdirectories below a given directory?" Let me defend each of these assertions in turn. The first concerns deleting a strange filename. It is my firmly held opinion that IF YOU CAN'T FIGURE IT OUT, YOU SHOULDN'T BE POSTING IN COMP.UNIX.WIZARDS. Go back to comp.unix.questions. This question has been asked and discussed in c.u.w WAY TOO MANY TIMES, and it's getting old. The second complaint I mentioned above has to do with a recent question posted to c.u.w. It read as follows: "I'm interested in finding a unix command usage that will return the complete path names of all subdirectories below a given directory..." In other words, the person asking the question wanted to be able to do "find <dir-name> -type d -print." I object to this question for two reasons. First, THIS IS NOT A "WIZARD"-LEVEL QUESTION! There is nothing whatsoever difficult about it. It should not present a problem to anybody who knows anything at all about Unix. And, if it does, then IT SHOULD HAVE BEEN POSTED IN COMP.UNIX.QUESTIONS. The second complaint I have is that in response to this question, a multitude of people posted messages TO THE NET answering it. Many of them were wrong or silly over-answers to a simple question, and ALL of them should have been sent in private E-mail for the person who asked the question to summarize. Let's look at the answers to this question which were posted (names omitted to protect the guilty): 1: I am sure there are lots of ways to do this. Here's a recursive C program to do it. It has its own limitations like maximum path length. I have a tree printing version of it too. It uses curses, terminfo etc. The listing for syserr.h is also included. [incredible overkill C program to do what "find <dir> -type d -print" does already] Surely you can't be serious! Has this guy ever heard of find(1)? 2: find directoryname -type d -print OK, this is correct answer number one. 3: find dirname -print This is close, but it ignores the fact that the person who asked the question only wanted to list directories, not files. 4: find /files/home/users -type d -print This is correct answer number two. 5: Why not simply use find /foo -type d -print ? Unless I misunderstand what you are trying to do, this does it.... This is correct answer number three. 6: [In response to earlier correct answers] Almost. Don't forget to pipe it to `sort', [sic -- punction outside of quotation marks? tsk, tsk :-)] as find doesn't. And <name deleted> forgot that he asked for directorys [sic] only. One thing I recently discovered is that find takes multiple directorys [sic] before the options: find /here /there /everywhere -dothis -dothat ... I guess we should call this a "correct answer," so this is correct answer number four. And I'll bet that all of us were enlightened to find out that find can take multiple paths on which to operate. I guess that's what the man page means when it says that "find pathname-list expression" is the usage, and a "pathname-list" is "(i.e. one or more pathnames)." 7: [in response to the wonderful C program mentioned above] "Yes, there are lots of ways; using the already-written "find" command is far easier than writing your own program to do the same thing...." Yes, this is true. But gee, look, you haven't explained how to do it! What a useful answer! I'm afraid this one can't be classified as a "correct answer." Sorry, you don't win the prize.... 8: .... Um... am I missing something or doesn't du -a . or du -a your_favorite_directory do all this stuff without the fuss and muss? Is this really a "wizards" type question? Yes, you apparently are missing something. First of all, the guy who asked the question only wanted directory names, not filenames, and "du -a" lists filenames. You would have been closer if you'd suggested just "du" rather than "du -a." Second, this has the unfortunate side effect of printing the size of every directory in addition to its path. Did the person asking the question say he wanted to do this? If so, then I missed it. 9: Give this script a spin around the block [shell script that (get a load of this!) takes each directory specified on the command line and runs "find <dir name> -type d -exec ls -d {} \;" on it] Gee, it looks like you know about the find(1) command, but you're completely confused.... has it occurred to you that find takes multiple paths on the command line, or that the user asked for a recursive listing and your script will not list recursively? I thought not. The net (pun intended) result of all this is eight responses posted in comp.unix.wizards to a question that should never have gone into c.u.w. in the first place. Besides that, only four of the eight messages provided the "correct" solution to the problem. CAN YOU SAY, "MAJOR TEN-TON LOSE?" I thought so. \end{Hugeflame} OK, let me reiterate the points I've tried to make in this posting: 1. Please, please, don't post a question to comp.unix.wizards unless you really are convinced that it's going to take the combined brain power of multiple "wizards" to answer your question. Comp.unix.questions should be your first resort in questions about Unix unless you are 100%, cross-your-heart-and-hope-to-day sure that your question is not a simple one. 2. When someone asks a question on the net and it is likely that several people will respond, ANSWER THE QUESTION IN E-MAIL! DON'T post an answer to the net. 3. If you AREN'T a wizard, DON'T answer questions in comp.unix.wizards! I hate to be blunt, but it's just plain STUPID (IMHO) to post a C program and a shell script to do what find(1) is designed to do! OK, I'm off my soapbox. I feel much better now. Jonathan Kamens USnail: MIT Project Athena 410 Memorial Drive, No. 223F jik@Athena.MIT.EDU Cambridge, MA 02139-4318 Office: 617-253-4261 Home: 617-225-8218
ray3rd@ssc-vax.UUCP (Ray E. Saddler III) (05/24/89)
In article <11619@bloom-beacon.MIT.EDU>, jik@athena.mit.edu (Jonathan I. Kamens) tells us: # # [many many bytes of flame-data deleted, except for his slam about # my contribution which causes him great pain: ] # # 9: Give this script a spin around the block # Jon, thanks for not providing my name to protect my guilt, you have impeccable class! # # [shell script that (get a load of this!) takes each directory # specified on the command line and runs "find <dir name> -type d # -exec ls -d {} \;" on it] # Heh! Whatta maroon! Can you beleive it?! # # Gee, it looks like you know about the find(1) command, but you're # completely confused.... has it occurred to you that find takes # multiple paths on the command line, or that the user asked for a # recursive listing and your script will not list recursively? I # thought not. # Gee, Jon, you're right! I *did* notice after posting, that I had a misaligned head; I'm used to seeking a full 'ls' with full pathnames in my find-on-the-fly usage of: find <dir> -exec ls -ldF {} \; So, after realizing this, an attemt to 'C'ancel using readnews was done, but I was told by the readnews software that I couldn't cancel something I didn't create, (which wasn't the case). I'm glad you brought my error and infraction of protocol to public attention, you see, ignorant people like myself need to be made examples of. # OK, I'm off my soapbox. I feel much better now. I'm so glad. I suppose an e-mail message to you would have been more appropriate, but I felt that a public acknowledgement [might] be meaningful, it seems to have worked for you. Have a nice day. > Jonathan Kamens USnail: > MIT Project Athena 410 Memorial Drive, No. 223F > jik@Athena.MIT.EDU Cambridge, MA 02139-4318 > Office: 617-253-4261 Home: 617-225-8218 -- Ray E. Saddler III | __ __ __ __ | UseNet Boeing Aerospace | / / / // //| // | uw-beaver!ssc-vax!ray3rd P.O. Box 3999 m.s. 3R-05 | /-< / //- // |// _ | PhoneNet Seattle, Wa. 98124 USA | /__//_//__ // //__/ | 1+206-657-2824
root@chessene.UUCP (Mark Buda) (05/25/89)
In article <215@cs.columbia.edu>, olasov@cs.columbia.edu (Benjamin Olasov) asks: > I'm interested in finding a unix command usage that will return the complete > path names of all subdirectories below a given directory, so that, given a > directory tree like this: > > What's the easiest way to do this? In article <2673@ssc-vax.UUCP> ray3rd@ssc-vax.UUCP (Ray E. Saddler III) responds: >Give this script a spin around the block: ... > find $I -type d -exec ls -d {} \; ... Um, he asked for the *easiest* way. find $I -type d -print is much easier. Mark Buda hermit@chessene.uucp / hermit%chessene.uucp@uunet.uu.net ...!rutgers!bpa!vu-vlsi!devon!chessene!hermit / devon.lns.pa.us!chessene!hermit King of the Dancing Walnuts PS: Anybody know why using ^Z on the console logs me out?
peter@ficc.uu.net (Peter da Silva) (05/26/89)
In article <2673@ssc-vax.UUCP>, ray3rd@ssc-vax.UUCP (Ray E. Saddler III) writes: > do > find $I -type d -exec ls -d {} \; > done > fi Ack. At the very least: find $I -type d -print But find is a hog. I generally do: du $I | cut -f2 -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.