rename Command in Linux: Batch Rename Files with Perl Regex

The rename command in Linux renames multiple files at once using Perl regular expressions. Unlike mv, which handles one file at a time, rename applies a pattern across every matching filename in a single operation.

Two versions exist. The Perl version (available as renameprename, or file-rename) uses full Perl regex. The C version (from util-linux) uses a simpler rename oldstr newstr files syntax. To check which is installed:

bashrename --version

Output containing “File::Rename” or “perl” = Perl version. “util-linux” = C version. Install the Perl version if needed:

bashsudo apt install rename         # Ubuntu, Debiansudo dnf install prename        # Fedora, RHELsudo pacman -S perl-rename      # Arch

How to Use the rename Command in Linux

The syntax is:

bashrename [OPTIONS] perlexpr files

The most common form uses the Perl substitution operator:

bashrename 's/search/replace/' files

To change all .css files to .scss:

bashrename 's/\.css/.scss/' *.css

\.css escapes the dot because . in a regex matches any character. Without the backslash, .css would also match acss_css, or any character preceding css. The shell glob *.css expands the filenames before rename receives them.

Always test with -n before renaming. There is no undo:

bashrename -n 's/\.css/.scss/' *.css

Other useful flags:

  • -v – prints each file as it is renamed
  • -f – allows overwriting files whose target name already exists
  • -e – chains multiple expressions, applied in the order given:
bashrename -e 's/\.jpeg$/.jpg/' -e 'y/A-Z/a-z/' *.jpeg

This changes the extension first, then lowercases the full filename.

Perl Regex Patterns: s///, y///, Anchors, Flags, and Modifiers

Substitution (s///) matches a regex and replaces it:

  • s/old/new/ — replaces the first match only
  • s/old/new/g — replaces every occurrence in the filename
  • s/\.bak$// — removes .bak only at the end; $ anchors to the end of the string so .bak inside a longer name is not affected
  • s/^/prefix_/ — adds a prefix; ^ matches the start of the string
  • s/\.jpe?g$/.jpg/i? makes e optional; /i makes the match case-insensitive; matches .jpg, .jpeg, .JPG, and .JPEG

Transliteration (y///) maps characters one-to-one, similar to the shell tr command:

  • y/A-Z/a-z/ — converts each uppercase letter to lowercase
  • y/ /_/ — replaces every space with an underscore

The /e modifier evaluates the replacement as Perl code. This enables sequential numbering:

bashrename -v 'our $i; s/^/sprintf("%03d_", ++$i)/e' *.jpg

Each file gets a zero-padded three-digit prefix incremented across the batch.

Practical Examples and Handling Special Filenames

Common one-liners:

bashrename 's/\.bak$//' *.bak            # remove .bak extensionrename 's/^old_//' old_*.txt         # remove a prefixrename 's/^/project_/' *.txt         # add a prefixrename 'y/ /_/' *                    # spaces to underscoresrename 'y/A-Z/a-z/' *               # convert to lowercaserename 's/\.jpe?g$/.jpg/i' *        # normalize jpeg/JPEG to jpg

Filenames with spaces or special characters can break shell glob expansion. Use find with null-delimited output to handle them safely:

bashfind . -type f -name '*.txt' -print0 | xargs -0 rename -n 's/ /_/g'

-print0 separates filenames with null bytes instead of newlines. xargs -0 reads that null-delimited input so filenames containing spaces, newlines, or special characters reach rename intact. Remove -n once the dry run output looks correct.

Always run rename -n before committing to a batch rename. Use mv for a single file; use rename when you need a pattern applied across many filenames at once. Leave a comment below if you run into any issues.

Cyber Defence

Recent Posts

lsmod Command in Linux: List and Inspect Kernel Modules

The lsmod command in Linux lists all currently loaded kernel modules. It reads /proc/modules — a virtual file maintained…

58 seconds ago

pgrep Command in Linux: Find and Filter Running Processes

The pgrep command in Linux finds the PIDs of running processes based on a name or other…

20 hours ago

unlink Command in Linux: Remove a Single File or Symlink

The unlink command in Linux removes a single file by deleting its directory entry. It is a…

21 hours ago

How to Check Open Ports in Linux: nmap, netcat, and Bash

When troubleshooting a network connection or configuring a firewall, the first question is whether a…

21 hours ago

ifconfig Command in Linux: Configure Network Interfaces

The ifconfig command in Linux displays and configures network interfaces. It can assign IP addresses, bring interfaces…

22 hours ago

groupdel Command in Linux: Remove a Group and Audit Files

The groupdel command in Linux removes a group from the system. It deletes the group's entry from /etc/group and /etc/gshadow,…

2 days ago