Tuesday, March 29, 2005 6:29 PM | rahel luethy | 5 comment(s)

mv *.foo *.bar

unfortunately, this is not how you rename the extensions of multiple files in one go. the shell can't match *.bar and the mv command just doesn't work that way... here is one option for bulk renaming on unix: find . -name *.foo | sed "s/\(.*\)\.foo$/mv '&' '\1.bar'/" | sh it concatenates one mv command per file and pipes all commands to a shell. performing a search/replace over a big file system tree is another task which sounds very easy but is actually quite tricky. surprised that my java IDE (eclipse) doesn't offer anything alike, i switched to good'ol bash when i recently had to replace all occurrences of "foo" with "bar" in our source tree*: find . -name "*.java" | xargs sed -i -e "s/foo/bar/g" this seemed to work quite well. however, eclipse reported 42 zillion outgoing cvs changes (while probably only about 20 files contained the "foo" string). this behavior is intrinsic to sed (the stream editor) and the -i argument (the in place editing): sed reads the file, edits the stream, writes the result to a tmp file, and finally overwrites the original file with the tmp file. this last step is done for every single file, irrespective of whether an actual edit has been performed or not. if you don't want the timestamps to change, you thus need to sneak in an additional grep command: find . -name "*.java" | xargs grep -l foo | xargs sed -i -e "s/foo/bar/g" comments and sexy alternatives are very welcome! * no, we don't actually spend our afternoons replacing "foo" with "bar" at genedata... but i just don't want to rant about the difference between a java.security.InvalidParameterException and a java.lang.IllegalArgumentException any further ;-)

10:01 AM | Anonymous Anonymous said...

Don't try this at home:

es verkettet einen mv befehlen Sie pro Akte und Rohre alle Befehle zu einem Oberteil.

6:06 AM | Anonymous Anonymous said...

I like Ultraedit for such text munging thingies. Not that it's any better than Unix scripty things for the map {s/foo/bar/g;} (@files) task. What's worth the $35 is the selection and copypasting by columns and blocks, which combined with regexp replace-alls is addictively efficient.

2:58 PM | Anonymous Anonymous said...

If you still live in a windows-only world and can't use UnixUtils for some reason, give the following line a chance:

for /r %I in (*.foo) do ren "%I" "%~nI.bar"

11:37 AM | Anonymous Anonymous said...

for /r %I in (*.foo) do ren "%I" "%~nI.bar"

While I can't argue with the function of that statement, I can argue with its point.

ren *.foo *.bar works in windows.

As for renaming within files, I'm an Editplus diehard although I would find it difficult to do anything but draw in a matchup against a hardcore Ultraedit user. Actually I'd lose - Editplus doesn't do hex.

As far as eclipse goes, I find it highly irritating that in version 3 there's no "ignore files that havn't changed" option which was rather inconveniently stripped from version 2.x. Here's hoping for a revival.

12:41 PM | Anonymous Anonymous said...

Actually the windows-only variant that uses "ren" does not touch subdirectories, while the "for..." version does.