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 rename, prename, 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
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.
Substitution (s///) matches a regex and replaces it:
s/old/new/ — replaces the first match onlys/old/new/g — replaces every occurrence in the filenames/\.bak$// — removes .bak only at the end; $ anchors to the end of the string so .bak inside a longer name is not affecteds/^/prefix_/ — adds a prefix; ^ matches the start of the strings/\.jpe?g$/.jpg/i — ? makes e optional; /i makes the match case-insensitive; matches .jpg, .jpeg, .JPG, and .JPEGTransliteration (y///) maps characters one-to-one, similar to the shell tr command:
y/A-Z/a-z/ — converts each uppercase letter to lowercasey/ /_/ — replaces every space with an underscoreThe /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.
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.
The lsmod command in Linux lists all currently loaded kernel modules. It reads /proc/modules — a virtual file maintained…
The pgrep command in Linux finds the PIDs of running processes based on a name or other…
The unlink command in Linux removes a single file by deleting its directory entry. It is a…
When troubleshooting a network connection or configuring a firewall, the first question is whether a…
The ifconfig command in Linux displays and configures network interfaces. It can assign IP addresses, bring interfaces…
The groupdel command in Linux removes a group from the system. It deletes the group's entry from /etc/group and /etc/gshadow,…