klm@cme-durer.ARPA (Ken Manheimer) (05/09/88)
I have what ought to be a simple thing to do using find that actually seems to be beyond its capabilities. Can anyone out there reveal something i've overlooked? First of all, i'm dealing with the /usr/bin/find of Sun OS 3.5. The problem concerns pruning absolute paths from a directory-structure traversal. This is as opposed to pruning relative directory-names, which is easy to do using a '-name <dirname> -prune' clause. The problem is that i have only been successful using a <dirname> that has *no* path components (slashes). It's pretty clear to me, both from the wording in the man page (the fact that the -name argument is specified to take a 'filename' qualifier, rather than a 'pathname') and from the behavior, that in fact the -name argument will not accept pathnames, and i can't see any other way to accomplish what i want using find. Here's an example to illustrate: given directory structure: /usr/local/testdir/ / \ firstSub secondSub (/usr/local/testdir/{first,second}sub/) / \ / \ firstOne firstTwo secondOne secondTwo (leaf files) Then commands (with any embedded narrative comments in square brackets'[]':) -=- % cd /usr/local/testdir % find . -print . ./first ./first/firstOne ./first/firstTwo ./second ./second/secondOne ./second/secondTwo [now prune out contents of second, by specifying a '-print' and-ed with a -prune for the file named 'second':] % find . -print -name second -prune . ./first ./first/firstOne ./first/firstTwo ./second [That works fine. Now, a few attempts to prune matching on more elaborate pathnames for second:] % find . -print -name ./second -prune . ./first ./first/firstOne ./first/firstTwo ./second ./second/secondOne ./second/secondTwo % find /usr/local/testdir -print -name /usr/local/testdir/second -prune /usr/local/testdir /usr/local/testdir/first /usr/local/testdir/first/firstOne /usr/local/testdir/first/firstTwo /usr/local/testdir/second /usr/local/testdir/second/secondOne /usr/local/testdir/second/secondTwo -=- In case it's relevant, i'm doing all this to obtain a stream of filenames for input to a backup archiver. I'm already using the -name/-prune feature to bypass the contents of archetypal dirnames such as 'spool', 'tmp', and 'dev', but would like a way to prune out some of the parts of the standard sun distribution, such as '/usr.MC68020', without risk eg of pruning a users directory that they happened to name similarly ('/usr2/someone/stuff/usr.MC68020/'). Is it in fact the case that find will not perform a prune on the basis of a (non-trivial) pathname, or am i missing something essential? I know i could accomplish what i want using a post-filter, eg grep family, of the find output, but i am reluctant to do so for a few reasons, and in any event i'd like to be sure about how to properly use find. Thin kew in advance for any help, Ken Manheimer klm@cme-durer.ARPA or ..!uunet!cme-durer.arpa!klm National Bureau of Standards, Factory Automation System, Software Support A man must have chaos within him to give birth to a dancing star - Nietzsche
chris@mimsy.UUCP (Chris Torek) (05/10/88)
In article <435@stylus.cme-durer.ARPA> klm@cme-durer.ARPA (Ken Manheimer) writes: >... The problem concerns pruning absolute paths from a directory-structure >traversal. This is as opposed to pruning relative directory-names, >which is easy to do using a '-name <dirname> -prune' clause. It cannot be done directly. You *can* do this: find <path> -exec expr {} = /foo/bar \| {} = /foo/baz \; -prune -o <pred> This will not perform <pred> on /foo/bar and /foo/baz; if you want them done, but not any files within them, try find <path> \( -exec expr <exprs> \; ! -prune \) -o <pred> >Is it in fact the case that find will not perform a prune on the basis >of a (non-trivial) pathname...? It is. -prune simply says `do not search the current path any deeper', and then succeeds a la -print. (At least, that is what the one I put in on our Vaxen does, and I did it from the Sun documentation.) >... I know i could accomplish what i want using a post-filter ... That would probably be fastest. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (05/11/88)
Considering your application, you can get there from here by find . -name foo -print | egrep -v '\./name1|\./name1/" > file The problem is that -prune only looks at the current filename (basename). Therefore the name xxx is omitted from the output, but names of the format xxx/anything will not be. I do much the same thing, and drop anything with the string "/tmp/" in the name. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me