Globbing

Michael Neumann mneumann at ntecs.de
Thu Feb 14 07:58:57 PST 2008


Rahul Siddharthan wrote:
Bill Hacker wrote:
That said, I remain surprised that others haven't already said, and
sooner, rather than later, words to the effect:
'Yes, historical reasons quite aside, these common and frequently needed
tools can too often be more arcane than they need to be'.
It always surprises me how much of the Unix Hater's Handbook remains
valid.  

For example, how do you use "find" to find all files in a directory
that end in ".el" and don't have a corresponding ".elc" file?  
Answer:
 find . -name '*.el' -print  \
    |sed 's/^/FOO=/' \
    |sed 's/$/; if [ ! -f ${FOO}c ]; then echo $FOO; fi/'  \
    | sh
Hm, why don't you use a "real" language, instead of hacking shell
scripts. I understand that they are useful in some cases, as /bin/sh is 
cross-platform and installed by default. For anything else, take perl, 
python or ruby. In Ruby this becomes the following:

  Dir['**/*.el'].reject {|f| File.exist?(f + "c")}.each {|f| puts f}

And that's just a simple example. Once it gets more complex, the
power of more advanced scripting languages pay off a lot more.
When I want to do something like that to a large directory, I generate
a full directory listing and then write a python program to parse it.
That seems easier to wrap my mind around.  (The author of the above
find command used emacs-lisp instead, then figured out the correct
find incantation because it bothered him.  "It only took me 12 tries
to get it right.  It only spawns two processes per file in the
directory tree we're iterating over.  It's the Unix Way!")
If you have an Apple, you can use this one liner (because Ruby comes by 
default ;-)

find . -name "*.el" -print | ruby -lne 'puts $_ unless test(?e, $_ + "c")'

Regards,

  Michael





More information about the Kernel mailing list