renaming multiple files with bash

Sometimes you have an entire directory filled with files whose naming system is annoying, bothersome, or makes no sense. Sometimes they have lots of spaces and weird characters that make commands ungainly. Renaming every single one – especially when there could hundreds of files – would be impossible. So let’s use the the command line to fix this.

The first thing is you will need to loop over all the files in your directory. Here are two ways to do that. The second uses a text file with a list of file names in it. This sometimes happens to me when I’ve been webscraping for a list of files for download.

for f in *.txt; do SOMETHING; done
for in `cat filelist.txt`; do SOMETHING; done

The first way to do the name change or file extension change is to use built in substitution alongside the mv command. Here is also a list of different substitution patterns.

for f in *old_pattern*
do
    mv "$f" "${f/old_pattern/new_pattern}"
done

${FOO%suffix} Remove suffix
${FOO#prefix} Remove prefix
${FOO/from/to} Replace first match
${FOO//from/to} Replace all matches
${FOO/%from/to} Replace suffix
${FOO/#from/to} Replace prefix

There is an even faster way to do this through the rename command. This command is not automatically installed in bash, so you will need to install it. Using the n flag first will give you a preview. s means substitution. If you add a ^ in from of the unwanted pattern, it will only look for the pattern if it is the beginning of the string.

sudo apt-get install rename
rename -n 's/old/new/' *
rename 's/old/new/' *

Finally, you can also use the basename command.

mv $f `basename $f .txt`.jpg