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.