Lets start with an entry from:
Brian Rectanus
for f
in *.foobar; do
F=`echo $f|sed 's/\.[^.]*$//'`
mv $f $F
done
Very straight forward. Loop through every file, re-write the name
with sed and assign that to a second variable and then use "mv" to
rename it.
My first approach was almost identical to this except I used
"
sed 's/.foobar//'" -
substitute and empty string for ".foobar".
I think Brian's is much nicer.
It uses the expression "\.[^.]*$"
which says look for a period then match anynumber of non-period
characters at the end of a line. (The replace that with an empty
string) Nice use of regular expressions. And it does what I want
with "file.foobar.foobar",
(though I didn't explicitly say what I wanted done in that case.)
All in all a fine entry.
After thinking about "clever" solutions
for a while I came up with the following entry
(note:see fine print in the rules)
ls |
awk '{print} ;sub(".foobar$"," ");' | xargs -n2 mv
It uses awk to generate 2 names for every file listed by "
ls".
First it prints the original filename, then the new filename without
the ".foobar" suffix. "
mv"
will only take two arguments so I use
xargs
-n2 to keep running "
mv"
two arguments at a time. I think its a rather cute use of
xargs.
After reviewing all the other entries, I came up with the following
(note:see rules fine print again)
after reading man bash for a while...
for i
in `ls` ; do
mv $i ${i%.foobar}
done
Bash it seems will modify variables on the fly- the
${i%.foobar} says take the varible
"i" and
remove the .foobar at the end. I like this one because its rather
short (in number of characters).
On the other hand it uses some fancy bash features that I (almost)
stole from Benjy Cline's entry (since I wrote this after reading the
others).
Here's Benjy Cline's amazing entry
(slighty rewritten by me to be in the same form as the other entries.)
find .
-name \*.foobar -exec csh -c 'mv $* $*:gr' {} \;
No pipes, no explicit loops, short, sweet, and interesting...
The "
find ... -exec {}" is
rather straight forward (though fun).
It says find all files ending ing .foobar and run the follow command,
replacing "{}" with the file name.
"Find" is good for that; so far so good; but
WHAT THE HECK IS:
csh -c 'mv $* $*:gr' {}
I mean how does it work?!?
When it comes to computer problems (or nearly any problem these days)
I'm fond of the phrase "GOOGLE is your friend".
Has anyone tried to search for "$*:gr" ?? Well all I can say is
good luck! I couldn't
use google to find anything useful (or other search engines.)
When I first asked Benjy WTF? he said he didn't know either, and there
was no rule that he had
to know how it worked- (touche), but I think he was pulling my leg.
He later explained that in the C shell
$*
represents the filename passed to the script '
mv $* $*:gr'
(by
find ... {})
:r means remove the final
extension of a filename
(the "
g" means do it globally)
It looks like the authors of C shell had my problem in mind when they
wrote it.
While using "
:gr" doesn't do
what I wanted with "file.foobar.foobar" thats easy enough to fix
with ":r" and I didn't really specify what to do with that case in the
rules anyway.
Congatulations and thanks Benjy, both for your entry and explaining it
to me-
you
are the winner of this Geeks Lunch Contest. You should
appear or send a designated delegate to pick your choice of
white-hat hacker hat, or black-hat hacker hat at Geeks' Lunch today.
Don't know about you guys, but I learned a lot from this little
contest. If you think it wasuseful drop me a little note saying
so and I may do some more.