removing a file extension from a bunch of files

During my Ph.D. I used a VMS machine with GCG a great deal. Not a powerful machine by any stretch of the definition but it was there, accessible and had a copy of GCG with updated databases.

VMS has more than a few differences when compared to UNIX. A great feature is filesystem level versioning.All save operations will create a new version. Edit a file called “mess” and upon saving you will now have “mess;0” and “mess;1”. Edit it a subsequent time and you have “mess;2” and so on. This is a great way to fix a problem if you messed up editing it, Although having all those files in a directory does get a little annoying. I guess that the shell allowed you to only display the most current revision of a file but I never got around to finding how!

Anyway I recently had cause to revisit a bunch of sequences from my Ph.D. days and had to get rid of the extension of a whole bunch of files (a few thousand). Performing rename operations under UNIX is always a pain in the arse. Linux has the rename command which makes this easier (remember rename is just a mv), but I was doing this from OS X which has no such command. Normally when I come across such a missing app under OS X I’d use Fink to compile and install a missing command, but it seems there’s no package for it.

Basically I needed to do the following operation on many files:

mv './INTERESTING.LIST;4' './INTERESTING.LIST'

However that ;4 could be any digit from ;0 to ;10 depending how many times I’d edited the sequence under VMS.

For such renaming operations I would use ‘find’ and ‘xargs’, however, for the life of me I could not get it to work.

In the end I settled for the following command. It’s quite an elegant solution as it uses echo to send the substituted command through sed to remove the version number from the second iteration of the found file, and then pipe this through to the shell to execute it..

find . -name "*;4" -exec echo "mv '{}' '{}'" \;

sed 's/\;4//2'

The full command is:

find . -name "*;2" -exec echo "mv '{}' '{}'" \;| sed 's/\;2//2' | /bin/sh

I found this in a post on the Macworld Forums.

Of course if I had have been clever I’d have run this in a shell loop to perform for each digit. However, I’d wasted too much time as it is and I just ran the command ten times.

Technorati Tags: