Command Line Basics: Bulk Rename Files With rename
Sometimes you get a bunch of files that are named in an annoying way and you'd like to change the naming convention for all of them. Maybe you forgot to change the settings on your CD ripping software and it ended up creating a bunch of long file names that you don't like.
I recently received a bunch of files that stupidly had names starting with spaces and hyphens; ( - ). The files looked something like this:
linerd@laptop:~/demo$ ls -1 - File number 1.txt - File number 2.txt - File number 3.txt - File number 4.txt - File number 5.txt
Starting a file name with a space is just stupid! For 5 files it's no big deal to go in and manually rename them. I had many more files, so I was in search of a tool that could change many files all at once. The aptly named rename terminal command turned out to be a great solution.
rename uses Perl expressions to recognise and replace patterns in file names. Since the expression syntax is somewhat complex, rename includes the -n parameter, (no action,) so you can try the command before executing it. To test the command to strip the " - " from the above file names, you would use:
rename -n 's/ - //' *
This gives the output
- File number 1.txt renamed as File number 1.txt - File number 2.txt renamed as File number 2.txt - File number 3.txt renamed as File number 3.txt - File number 4.txt renamed as File number 4.txt - File number 5.txt renamed as File number 5.txt
Since the output of the test command looks good, you can make the changes to your files by re-running the command without the "-n" option.
rename 's/ - //' *
My listing of files now looks like this:
linerd@laptop:~/demo$ ls -1 File number 1.txt File number 2.txt File number 3.txt File number 4.txt File number 5.txt
Personally, I don't like spaces in my file names, so I'm going to run the command again to replace the spaces with underscores.
rename 's/ /_/g' *.txt
This command gives a result that looks like
linerd@laptop:~/demo$ ls -1 File_number_1.txt File_number_2.txt File_number_3.txt File_number_4.txt File_number_5.txt
Here's a little explanation about the above commands. The single quotes in the command are important to isolate the slashes and prevent them from being recognised as special characters by the shell. The slashes are field separators to separate the find field from the replace field. The "s" in the command stands for "substitute". The "g" that was used in the second version above stands for "global". Without it, only the first space would have been replaced with an underscore. The "*" or "*.txt" at the end of the command tells the shell which files should be affected.