creating pipes in find(1)

Rob Warnock rpw3 at redwood.UUCP
Thu Sep 27 20:07:25 AEST 1984


[ Wizards, be patient. This IS net.unix, ne? ]

+---------------
| How do I build a pipe within the exec portion of find? Example:
|	find /etc -name printcap -exec cat {} | lpr \;
| I've tried lots of combinations of escaped parens, exec'ing
| the shell, etc and nothing works...
| 	Terry Slattery	  U.S. Naval Academy	301-267-4413
+---------------

I have never gotten it to work either (except like your "junk" auxiliary
shell script), but the following neat/ugly/cute/hacky method sprang to mind
one day as I was reading Kernighan & Pike [pp 86-87ff, see also "pick"]:

	$ for i in `find . <pattern> -print`
	> do echo $i		# so we can see what we're doing
	> cat -v $i | lpr	# ...or anything you want at all...
	> done

For C-shell users, that's:

	% foreach i (`find . <pattern> -print`)
	? echo $i	# so we can see what we're doing
	? cat -v $i | lpr
	? end

This lets you do more than one thing to the file, as well. Normally, the
"{}" token can be used exactly once, so things like "mv {} {}-" don't work.
Here, you can play games like "mv $i olddir/`basename $i`.old", and such.

K & P also show an example of using "grep" to select files by their contents.
Since this is USENET, I will make it news-oriented (let $SN be your spool dir):

$ for i in `grep -l '^Subj.*[aA]pple.*[sS]haft' \`find $SN/net/micro -print\``
> do echo $i
> pr -h Apple-Shaft-Articles $i | lpr
> done

This will print each article in "net.micro.all" that contains "Apple...Shaft"
in the subject line, as in a recent set of postings. (Surprise! The upgrade
controversy raged across several groups!)

[I tried this. It worked. However, I had just done a severe "expire". So,...]

WARNING: Make sure that the "find" is not going to give you so much stuff
that your shell (or your system) blows up from an over-large argument list.
(That is, DON'T do "for i in `find / -print`")

An example of practical uses includes going through the news spool area
fixing up ownership, group, and modes of any directories that created by
"root" or "uucp" instead of "news" (seems to occasionally happen):

	$ for i in `find /usr/spool/news ! -user news -print`
	> do ls -adl $i		# show the culprit
	> /etc/chown news $i
	> /etc/chgrp news $i	# for those who don't have chowngrp
	> chmod 755 $i		# or whatever protection you run with
	> done

I'm sure you can think of lots of uses.

WARNING#2: If the command string gets so long (more than 2-3 lines) that
your error rate typing it wipes out the savings you got from using "immediate
mode", go back and edit a real shell script to do the work, test it on a
couple of files, then feed it to a "find ... -exec <script> \;". It's safer.

Rob Warnock

UUCP:	{ihnp4,ucbvax!amd}!fortune!redwood!rpw3
DDD:	(415)369-7437
Envoy:	rob.warnock/kingfisher
USPS:	Suite 203, 4012 Farm Hill Blvd, Redwood City, CA  94061



More information about the Comp.unix mailing list