
Script to rename thousands of files and directories?I need to rename thousands of files in MacOS, buried in subdirectories, changing " " to "_". I've found a ton of scripts using Google that purport to do this, but none of them actually work right. Can you please send me a script that does this? I also tried Automator, but it doesn't recurse into subdirectories. Filenames may have multiple spaces (eg "Holidays/Christmas/Gifts & Stockings (A - G)/stocking.png"). Directory names may have spaces, too. This is an interesting little programming task and a good demonstration of how double substitution can be your friend even if it looks like a less than elegant solution. To accomplish this task, I've written a shell script on my Mac OS X box that first goes through a directory tree and converts all the directories themselves from "a b" to "a_b", then goes through a second time to fix up all the individual files. The key idea here is that rather than fight the shell's desire to break up filenames at each space, I'll simply replace each space with a pattern that's extremely unlikely to occur ("___"). Here's the script: #!/bin/sh
# first, we fix the directories for name in $(find . -type d -print | sed 's/ /____/g') do if [ $name != "." ] ; then oldname="$(echo $name | sed 's/____/ /g')" newname="$(echo $name | sed 's/____/_/g')" if [ "$oldname" != "$newname" ] ; then echo "renaming \"$oldname\" to $newname" mv "$oldname" "$newname" fi fi done echo "" echo "done with directories, fixing individual files..." # now let's fix the files therein using almost identical code for name in $(find . -type f -print | sed 's/ /____/g') do oldname="$(echo $name | sed 's/____/ /g')" newname="$(echo $name | sed 's/____/_/g')" if [ "$oldname" != "$newname" ] ; then echo "renaming \"$oldname\" to $newname" mv "$oldname" "$newname" fi done exit 0 Notice in the first loop, where we fix the directory names, that there's a special test for the "." match: even though there are no spaces in the directory name, it still makes the script get a bit confused about the substitution, so it's easily sidestepped. Otherwise that's all there is to it: you should be able to use this script to easily "webify" your file and directory names, and it would be a straightforward extension to change the "newname" test to also either strip out or convert unwanted punctuation characters too, including "&" and "%", if they were possible names.
Help others find this article at Del.icio.us, Digg, Netscape, Reddit, and Stumble Upon
Categorized:
Shell Script Programming
(Article 6501)
Tagged: file name conversion, mac os x scripting, shell script programming Previous: Why does iTunes and my iPod show multiple titles for the same album? Next: Can other people view my saved passwords in Firefox? Subscribe!
Never miss another useful Q&A article again! Subscribe to AskDaveTaylor with Google Reader. oh boy i don't even know where to begin with this one :( OK here goes: command | while read baz; do stuff;done 2)DO NOT try to fight the shell ! Word splitting is there for a very good reason and bash has all the tools to work with it. 3)Study the possible input. What happens when a filename contains a newline? or a hyphen ? that's right, your script fails ! The right delimiter to use is $'\0' since filenames can't contain it. This is another reason not to use for loops, but while read -d $'\0' along with find's -print0 . 4)limit the input. why should your script operate on files that don't even contain spaces ? huh ? 5)avoid using sed for such a trivial task. Use parameter expansion instead, like foo=${foo// /_}.man bash, section parameter expansion 6)help echo good luck ! Posted by: monsieur at May 17, 2006 8:12 AMGreat ideas for tweaks and modifications. Remember, though, that one of the key concepts for these sort of throwaway (e.g. "use once") scripts is that quick and dirty trumps elegant and optimized. If this were a script I'd use from a cron job every 15 minutes for the next six years I'd write it differently, but for a lot of people who work within the Unix or Linux environment, learning how to get it done and get on with their job is far, far more valuable than learning The One Best Way to do things. :-) Posted by: Dave Taylor at May 17, 2006 4:42 PMoh, quick and dirty ey ? find . -type d -iname '* *' -exec sh -c 'mv "$1" "${1// /_}"' -- {} \; No need for a script then :P Seriously, being correct is ALWAYS more important than being fast in the real world. If you learn the right way to write shell scripts, it WILL save time in the long run (whether it's a production machine or a desktop!). Trust me on this one. Anyway, at least learn how word splitting works and why it's there, it'll pay back quickly, i promise ;) Posted by: monsieur at May 19, 2006 7:01 AMHow about handling filenames like: Hey! Santa's Movie.mpg
eg: thanks in advance..!! Posted by: evuraan at May 31, 2006 10:21 PMmeh, none of this appears to work right for: Quick and dirty should at least work fully the first time it's run not requiring multlple runs to make sure it gets everything. Posted by: Someguy at March 22, 2007 1:57 PMHello Dave ! In this example (and similar in others) You use for name in $(find . -type f -print | sed 's/ /____/g') You get here after the substitution of the find . -type f -print | sed 's/ /____/g' | while read name keep on doing and nice greetings from germany ! Posted by: harald eck at December 31, 2007 8:53 AMhi dave, i have been trying to write a script for mac OSX. i need to rename files eg : can a script be written for this? thanks hi dave Can this script be written? thanks That's quite easy, Akbar. Look at the "for" loop, then figure out how to transform a current filename into a new filename. Something like this: for name in *jpeg I'll let you figure out the transformation in the above. :-) Posted by: Dave Taylor at October 9, 2009 9:56 AMI have something to say, now that you mention it, but ...
I do have a comment, now that you mention it!
|
![]()
Search
Find just the answers you seek from among our 2300+ free tech support articles by using our Lijit search engine.
Help!
Subscribe to
Ask Dave Taylor!
Free Updates!
Sign up and get free weekly updates and special offers on books, seminars, workshops and more.
Articles and Reviews
Auctions and Online Shopping Blogs and RSS Feeds Building Web site traffic Business and Management Cell Phones and Mobile Phones CGI Scripts and Web Site Programming Computer and Internet Basics d) None of the Above HTML and CSS Industry News and Trade Shows Mac OS X Help MySpace, Facebook, Twitter and Social Network Help Pay Per Click (PPC) Search Engine Optimization Shell Script Programming Sony PSP, MP3 Players, Etc. The Writing Business Unix and Linux Help Video Game Tips and Help Windows Help
Recent Entries
Book Links
|