Renaming Many Files

Problem

You want to rename many files, but mv *.foo *.bar doesn’t work. Or, you want to rename a group of files in arbitrary ways.

Solution

We presented a simple loop to change file extensions in Changing Pieces of a String; see that recipe for more details. Here is a for loop example:

for FN in *.bad
do
    mv "${FN}" "${FN%bad}bash"
done

What about more arbitrary changes? For example, say you are writing a book and want the chapter file names to follow a certain format, but the publisher has a conflicting format. You could name the files like chNN=Title=Author.odt, then use a simple for loop and cut in a command substitution to rename them.

$ for i in *.odt; domv "$i" "$(echo $i | cut -d'=' -f1,3)"; done

Discussion

You should always use quotes around file arguments in case there’s a space. While testing the code in the solution we also used echo and angle brackets to make it very clear what the arguments are (using set -x is also helpful).

Once we were very sure our command worked, we removed the angle brackets and replaced echo with mv.

# Testing$
for i in *.odt; doecho "<$i>" "<$(echo $i | cut -d'=' -f1,3)>"; done <ch01=Beginning Shell Scripting=JP.odt> <ch01=JP.odt> <ch02=Standard Output=CA.odt> <ch02=CA.odt> <ch03=Standard Input=CA.odt> <ch03=CA.odt> <ch04=Executing Commands=CA.odt> <ch04=CA. odt> [...] # Even more testing $ set -x $ for i in *.odt; do echo "<$i>" "<$(echo $i | cut -d'=' -f1,3)>"; done ++xtrace 1: echo ch01=Beginning Shell Scripting=JP.odt ++xtrace 1: ...

Get bash Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.