gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/24/89)
In article <1627@ncar.ucar.edu> rob@scdpyr.ucar.edu (Robert Montgomery) writes: >Often it would be simpler to specify what I *don't* want in filename >substitution than what I do. For example, I would like to do something >similar the following: > ls {NOTfrog}.c >and have it produce: > bird.c fish.c Unfortunately the shell's pattern expansion capabilities support only a subset of the regular expression capabilities that you might expect of a UNIX utility. However, therein lies the clue: use some other UNIX utility. For example: ls `echo *.c|sed 's/frog.c/ /'` Not as convenient as what you really want, but at least the capability is available.
pete@escher.intel.com (Peter Johnson ~) (03/24/89)
In article <9911@smoke.BRL.MIL>, gwyn@smoke (Doug Gwyn ) writes: >In article <1627@ncar.ucar.edu> rob@scdpyr.ucar.edu (Robert Montgomery) writes: >>Often it would be simpler to specify what I *don't* want in filename >>substitution than what I do. For example, I would like to do something >>similar the following: >> ls {NOTfrog}.c >>and have it produce: >> bird.c fish.c > >Unfortunately the shell's pattern expansion capabilities support only >a subset of the regular expression capabilities that you might expect >of a UNIX utility. However, therein lies the clue: use some other >UNIX utility. For example: > ls `echo *.c|sed 's/frog.c/ /'` >Not as convenient as what you really want, but at least the capability >is available. 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. Peter Johnson pete@escher.intel.COM {amdcad,decwrl,hplabs,oliveb,pur-ee,qantel}!intelca!mipos3!pete
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/25/89)
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
dgk@ulysses.homer.nj.att.com (David Korn[drew]) (03/25/89)
In article <9911@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes: > In article <1627@ncar.ucar.edu> rob@scdpyr.ucar.edu (Robert Montgomery) writes: > >Often it would be simpler to specify what I *don't* want in filename > >substitution than what I do. For example, I would like to do something > >similar the following: > > ls {NOTfrog}.c > >and have it produce: > > bird.c fish.c > ksh-88 has expanded the file matching capability to allow such matches. The pattern !(frog) matches anything except frog, so that ls !(frog)*.c matches any thing that ends in .c that does not start with frog. More commonly, ls !(*.o) matches anything except *.o. You can use | for alternation. For example ls !(foo|bar)*.c whill not match anything beginning with foo or bar. The notation ?(pattern-list) matches 0 or 1 or any pattern in list. +(pattern-list) matches 1 or more *(pattern-list) matches 0 or more of any pattern in list. Of course these pattern can also be used with case statement and substrings.
scs@adam.pika.mit.edu (Steve Summit) (03/25/89)
In article <1627@ncar.ucar.edu> rob@scdpyr.ucar.edu (Robert Montgomery) writes: >Often it would be simpler to specify what I *don't* want in filename >substitution than what I do. For example, I would like to do something >similar the following: > ls {NOTfrog}.c >and have it produce: > bird.c fish.c A nice solution which I have not seen mentioned yet is the "pick" program, described in Kernighan and Pike's book, The Unix Programming Environment. You always invoke pick inside of backquotes, viz.: command `pick *.c` and you get to answer yes or no for each filename. It'd be silly for the ls example (but then again, so would anything; the problem comes up more typically when the command in question is going to modify the files somehow). pick essentially allows you to add an "inquire" facility to any program; for instance, rm -i * is equivalent to rm `pick *` The only problem with pick is that people who use the MH mail system already have another meaning for the command. For simply listing files, I find that postprocessing (rather than preselecting) is usually more convenient. For example, a frequent idiom of mine is ls -lt | grep -v '\.o$' to see what source files I've changed lately. If you can neither find a copy of Kernighan and Pike (as I recall, it included source code) nor write pick yourself (the only tricky part is using /dev/tty) I can send you my implementation. (I ought to just include it here; it's under 50 lines long.) Steve Summit scs@adam.pika.mit.edu
tr@madeleine.ctt.bellcore.com (tom reingold) (04/04/89)
On the subject of "filename substitution question", rob@scdpyr.ucar.edu
(Robert Montgomery) writes:
$ Often it would be simpler to specify what I *don't* want in filename
$ substitution than what I do. For example, I would like to do something
$ similar the following:
$
$ ls {NOTfrog}.c
$
$ and have it produce:
$
$ bird.c fish.c
$
$ Have I overlooked a "NOT"/"EXCEPT"/"EVERYTHING-BUT"-type special
$ character in the man pages? Or is there another simple way to do this
$ simple action in Unix (e.g., sunOS 4.0 or BSD4.3)?
While everyone's solutions have been more elegant than mine, I think
I should post the most obvious one.
ls | grep -v frog.c
(And it was quite a coincidence that David Korn mention the new feature
of ksh's regular expressions. I read the article yesterday morning and
wished we could get the new ksh. Then it arrived last night.)
Tom Reingold |INTERNET: tr@ctt.bellcore.com
Bell Communications Research |UUCP: bellcore!ctt!tr
444 Hoes La room 1E225 |PHONE: (201) 699-7058 [work],
Piscataway, NJ 08854 | (201) 287-2345 [home]
friedl@vsi.COM (Stephen J. Friedl) (04/05/89)
[ how do we list all files *except* mentioned ones? ] In article <15131@bellcore.bellcore.com>, tr@madeleine.ctt.bellcore.com (tom reingold) writes: > While everyone's solutions have been more elegant than mine, I think > I should post the most obvious one. > > ls | grep -v frog.c > Be careful here. Many versions of ls columnize their output, so the above will exclude everything that appears on the same line as the mentioned file. This can happen either by ls's default action or by aliases or shell functions defined by {/etc/,.}profile. Steve -- Stephen J. Friedl / V-Systems, Inc. / Santa Ana, CA / +1 714 545 6442 3B2-kind-of-guy / friedl@vsi.com / {attmail, uunet, etc}!vsi!friedl "I do everything in software, even DMA" - Gary W. Keefe (garyk@telxon)
gwyn@smoke.BRL.MIL (Doug Gwyn ) (04/06/89)
In article <1083@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes: >> ls | grep -v frog.c >Be careful here. Many versions of ls columnize their output, ... But not when their standard output is other than a terminal (!isatty(1)).