Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!pasteur!ames!elroy!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.unix.wizards Subject: Re: filename substitution question Message-ID: <4652@jpl-devvax.JPL.NASA.GOV> Date: 24 Mar 89 20:13:01 GMT References: <1627@ncar.ucar.edu> <9911@smoke.BRL.MIL> <3806@mipos3.intel.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA. Lines: 44 Peter Johnson writes: : I use a program written by Chris tweed called "sets". This program : just does set operations on its arguments. So for example if you : wanted to remove all files except those that end in .c or .h you : can do something like this: : : rm `sets * -d *.c` : : The -d stands for set difference. Sets also supports intersection and union. : : If you are interested, let me know and I will mail you a copy. Just for the fun of it, here's about 1/2 hour's work in perl, one screenful. I don't know if the tokenization or precedence is the same as the other version, but this version of sets will do parens (the other one might too, for all I know). It's likely shorter. And it would be trivial to add new operators--one line apiece. #!/usr/bin/perl $setnum = 0; $setstring = "\$set${setnum}_{\$_}"; while ($#ARGV >= 0) { $_ = shift; if (/^-[diu]$/) { ++$setnum; $setstring = "\$set${setnum}_{\$_}"; $expr .= '&&!' if /^-d/; $expr .= '&&' if /^-i/; $expr .= '||' if /^-u/; } elsif (/^[()]$/) { $expr .= $_; } else { $universe{$_} = 1; $expr .= $setstring; $setstring = ''; eval "\$set${setnum}_{\$_} = 1;"; } } eval "for (keys(universe)) { delete \$universe{\$_} unless $expr; }"; print join(' ',sort keys(universe)),"\n"; Larry Wall lwall@jpl-devvax.jpl.nasa.gov