Rename Multiple Files

To quickly rename a bunch of files, use rename.1

For example, here’s how you’d lowercase everything in the current folder:

rename --force --lower-case *

rename is especially useful for things like changing case, adding and removing strings, or finding and replacing patterns in filenames.

Here are some more examples showing how it works:

To get started now, skip to How to Install. For additional resources, see References.

Targeting Files

You can select files with glob patterns.

  • rename [options] *: Rename all files in the current folder.
  • rename [options] *.jpg: Rename all .jpg files in the current folder.
  • rename [options] **/*.jpg: Rename all .jpg files in this folder and all subfolders.

I’ll use *.jpg in the rest of my examples, but know you can replace that with any glob pattern to match your own files.

P.S. You can also pass multiple patterns, so the following examples will also work.

rename [options] *.jpg *.jpeg
rename [options] folder1/*.jpg folder2/*.jpg
rename [options] file1.jpg file2.jpg file3.jpg

Changing Case

Use --lower-case, --upper-case, and --camelcase to change the case of all matching files.

rename --force --keep-extension --upper-case *.jpg
  • --force: macOS and other systems are case-insensitive by default, meaning they think “FILE.jpg” and “file.jpg” are the same filename. Unless you force it, rename will not change those filenames because the file “already exists.”
  • --keep-extension: By default, changes apply to the entire filename—including the file extension. If you don’t want to accidentally change your file extensions, add this option to the beginning of your command. (Since rename applies its options sequentially, if you add the option too late then your transforms will apply first—before “keep” can take effect.)

Adding Strings

Use --prepend or --append to add strings to the beginning or end of all matching files.

rename --prepend 'example-' *.jpg

This adds “example-” to the beginning of all the text files in the current folder.

Removing Strings

Use --delete or --delete-all to remove strings from all matching files.

rename --delete 'example-' *.jpg

This removes “example-” from all the text files in the current folder.

Note: --delete only removes the first match from a filename. If the string you’re trying to remove shows up more than once in a filename (e.g., example-example-file.jpg) and you want to remove all matches, use --delete-all instead.

Finding and Replacing Strings

Use --subst or --subst-all to change “find” to “replace” in all the text files in the current folder.

rename --subst-all 'find' 'replace' *.jpg

Note: Like --delete, if you only want to substitute the first match in a filename then you can just use --subst. Personally, I use --subst-all more often.

Regular Expressions

Now it gets real: the full power of regular expressions in a handy renaming tool.

rename --expr 's/find/replace/g' *.jpg

You can literally do all the other examples we’ve covered with just the --expr option—it’s that powerful.

  • Changing Case: rename --expr 's/([A-Z])/\l$1/g' *.jpg2
  • Adding Strings: rename --expr 's/^/prepend-/' *.jpg3
  • Removing Strings: rename --expr 's/delete//' *.jpg4

Bonus: The --expr option is implied for the first expression, so you can simply pass your regex argument and it will still work.

rename 's/find/replace/g' *.jpg

Combining Transforms

rename’s options are applied sequentially, which means it applies each option one at a time in order. (This is especially important for options like --keep-extension.)

That means you can apply multiple transforms in a single command.

URL-Friendly Filenames

Here’s how you can combine multiple transforms to make all your filenames URL-friendly (i.e., lowercase with dashes).

rename --force --lower-case --sanitize --subst-all '_' '-' *.jpg
  • --force: Force filename changes, even if my operating system thinks they’re the same.
  • --lower-case: Lowercase the whole filename.
  • --sanitize: Replace all whitespace, control characters, and meta-characters with underscores.
  • --subst-all '_' '-': Change all underscores to dashes.
  • *.jpg: Rename all .jpg files in the current folder.

Numbering Files

Bonus round! rename also includes a built-in counter, so you can easily number (or renumber) all your files.

rename --keep-extension --expr 's/^\d+//' --counter-format 001 --expr 's/$/-$N/' *.jpg

This replaces prefixed numbers in the filename with a zero-padded suffix (e.g., changing 1-file.jpg to file-001.jpg).5

  • --keep-extension: Don’t apply changes to the file extension.
  • --expr 's/^\d+-//': Use regex to replace any numbers (\d+) followed by a dash(-) at the beginning of the filename (^) with an empty string.
  • --counter-format 001: Format the counter with padded zeroes, and start counting at 1. This sets the value for $N in the next expression, and will output 001, 002, etc. (If you want, you can also start counting at 0 with 000, or just about any other number.)
  • --expr 's/$/-$N/': Use regex to append a dash (-) and the current counter value ($N) at the end of the filename ($).
  • *.jpg: Rename all .jpg files in the current folder.

Testing

With so much power, it’s easy to make mistakes. That’s why rename has a --dry-run option. Add this to show what files would be renamed without actually changing anything.

rename --dry-run --verbose [options] *.jpg
  • --dry-run: Don’t actually make any changes. Just show me what would happen.
  • --verbose: Log everything that happens when I run the command.

(I’d recommend always including --verbose, or its abbreviation -v.)

Options & Abbreviations

For all you power users out there, there are abbreviations for almost every option, so you can trim longer commands down to snippets like rename -cf * (lowercase everything).

Here’s a quick list of all the options we’ve used in this post:

Switches

  • -f/--force: Force filename changes, even if my operating system thinks they’re the same.
  • -n/--just-print/--dry-run: Don’t actually make any changes. Just show me what would happen.
  • -N/--counter-format: Format and set the $N counter variable.
  • -v/--verbose: Log everything that happens when I run the command.

Transforms

  • -a/--append: Add text to the end of the filename.
  • -A/--prepend: Add text to the beginning of the filename.
  • -c/--lower-case: Lowercase the filename.
  • -C/--upper-case: Uppercase the filename.
  • -d/--delete: Delete the first match in a filename.
  • -D/--delete-all: Delete all the matches in a filename.
  • -e/--expr: Apply a Perl expression to the filename (e.g., a regex).
  • -s/--subst: Substitute the first match in a filename.
  • -S/--subst-all: Substitute all the matches in a filename.
  • -X/--keep-extension: Don’t apply changes to the file extension.
  • -z/--sanitize: Replace all whitespace, control characters, and meta-characters in the filename with underscores.

To see a full list of options & abbreviations, just run rename without any options in your terminal to view the “Usage” docs.

And that’s it for today!

How to Install

Use Homebrew to install rename on macOS.

brew install rename

For other operating systems, try searching for “linux rename install”.

References

The best way to learn more about rename is to check out its manual in your terminal.

rename --man

Beyond that, there’s a couple of dense Linux & Perl docs, a handful of good blog posts, and several scattered Stack Overflow answers to learn more from.

  1. Linux man pages: rename 

  2. Each of these examples deserves some more explaining, so here’s a quick breakdown of how the “Changing Case” expression works: rename --expr 's/([A-Z])/\l$1/g' *.jpg

    • s/…/…/ is a Perl expression. The s is a “substition operator.” It substitutes the match from the first part of the expression (between the first two slashes) with the content in the second part of the expression (between the last two slashes).
      • There’s also tr, the “transliteration operator” (aka y), which is probably the only other operator you’d use with rename. It can simplify some expressions (e.g., lowercase would just be y/A-Z/a-z/), but most of the time s should be all you need. For more details on Perl expressions, check out Perl Doc: Quote-Like Operators and Perl Doc: Regexp Quote-Like Operators.
    • ([A-Z]) matches all the uppercase characters and captures them in a “group” that we can access later with a “match variable” (that’s the $1 part towards the end).
    • \l lowercases the next character after it, which in this case is our match group, $1. In other words, it lowercases each uppercase character we find.
    • g at the end is a “global matching” modifier, which says to replace every match in the string, not just the first one we find. For more details on the g flag and other regex modifiers, check out Regular-Expressions.info: Perl Text Patterns for Search and Replace and Perl Doc: Using regular expressions in Perl - Global matching.

  3. You can also append text using the $ anchor instead of ^: rename --expr 's/$/-append/' *.jpg. For more details on anchors, check out Regular-Expressions.info: Start and End of String or Line Anchors

  4. This little regex simply says “replace the string ‘delete’ with nothing.” See note #2 above for more details on the “substition operator.” 

  5. If you just want to number your files, you can simplify this command: rename --keep-extension --expr 's/$/-$N/' *.jpg. Or if you want to replace the entire filename: rename 's/.*/$N.jpg/' *.jpg