Blog of Leonid Mamchenkov

You just stepped in a pile of posts.

Recursively renaming files in Linux

Posted in All on September 26th, 2005 · 4 Comments

One thing I liked about Linux is it’s hidden simplicity. When in a hurry, I usually go for the first working solution of a given problem. If the same problem appears often, I can get used to the first solution so much that I don’t even think about simplifying it.

A good example of this scenario is recursive renaming of files. It doesn’t happen that often though, but when it does, I am usually in a hurry and use the same old solution that I came across years ago. Here is how I am used to do it:

[me@here dir]$ #Recursively rename some to other
[me@here dir]$ for FILE in `find . -name somefile`
[me@here dir]> do
[me@here dir]> NEW=`echo $FILE | sed -e 's/some/other/'`
[me@here dir]> mv "$FILE" "$NEW"
[me@here dir]> done

Note that this is more of the base solution. Sometimes I have more parameters to find. Like when I don’t use sed at all and just use the -exec mv syntax. Sometimes I go as far as write a Perl script.

Obviously, this solution is very ineffecient and overdesigned. But it always worked for me.

Today I had to recursively rename a bunch of files and for once I wasn’t in a hurry. While I was slowly enterting in the characters and made a typing mistake, it occured to me that I am overdoing something. So I stopped and made a miniresearch. I spent much less than two minutes on finding a simplier and much nicer way of doing the same.

Apparently, there is a standard utility rename. It can change the name of the file fully or partially. It needs two parameters - what to change and to what to change it - and a list of file to work with. Here is how it can be used to solve the problem above:

[me@here dir]$ # Recursively rename some to other
[me@here dir]$ rename some other `find . name some`

Now that’s the beauty, isn’t it? It makes me think of all those characters I lost over the years…

Update: edited heavily to remove some nonsense that I typed for no good reason.

Tags: , , , , , ,

4 responses so far ↓

  • 1 Sam // Jun 16, 2006 at 9:45 pm

    Not a shell guy, but using ‘find…’ will split up filenames that have spaces, causing rename to not find the files it returns. Any ideas how to avoid that?

  • 2 Sam // Jun 16, 2006 at 11:22 pm

    Calling find in this way splits up file names when they have spaces, so:
    find . -name "*\?\*" -exec rename 'y/\?/_/' {} \;
    will avoid this problem (removing illegal question marks to copy to a fat drive here)

  • 3 Leonid Mamchenkov // Jun 16, 2006 at 11:35 pm

    Thanks for the fix, Sam.

  • 4 Ronak // Oct 26, 2008 at 3:23 pm

    I know this is an old post.. but thought you can help.

    I have a directory with many sub-dirs, that each have only 1 jpeg file in them and I want to rename them all to “folder.jpg”. The problem is each of the existing jpeg files has a unique name and they also have spaces.

    I was thinking about using the sed command in my script, but don’t know how to replace the whole file name and NOT just the extension.

    Here is what I have so far.. but its only removing the extension, on my replacement.

    find . -name “*.jpg” | while read FILE
    do
    echo “$FILE”
    nfile=`echo $FILE | sed ’s/\….$/folder.jpg/’`
    echo “$nfile”
    ##mv “$FILE” “$nfile”
    done

    Do you have any other ideas?

    Thanks

Leave a Comment

Note: This post is over 3 years old. You may want to check later in this blog to see if there is new information relevant to your comment.