Updated: 8 October 2026 · Applies to: Ubuntu 24.04 and 26.04, Debian 13 (Perl rename 2.02), AlmaLinux 10 (util-linux rename 2.40.2), bash 5

To rename all files in a directory in Linux, loop over them in bash and call mv for each one, for example for f in *.txt; do mv -- "$f" "${f%.txt}.md"; done. This works on every distribution. For pattern-based renames there is also the rename command, but it comes in two different versions: Ubuntu, Debian and Linux Mint use the Perl rename, while AlmaLinux, Rocky Linux, RHEL and Fedora use the simpler one from util-linux. Both are shown below, plus how to turn every file and folder name into lowercase.

Work on a copy or test first: both rename versions have a dry-run option (-n) that only prints what would change. For renaming a single file, see rename files and folders with mv and rename.

1. A bash loop with mv (any distribution)

Run these inside the directory (cd /path/to/dir). The quotes and -- keep names with spaces or leading dashes safe, and -n stops mv from overwriting an existing file.

# change the extension of every .txt file to .md
for f in *.txt; do mv -n -- "$f" "${f%.txt}.md"; done

# add a prefix to every file (folders are skipped)
for f in *; do [ -f "$f" ] && mv -n -- "$f" "old-$f"; done

# replace spaces with underscores
for f in *\ *; do mv -n -- "$f" "${f// /_}"; done

# number all .JPG files: photo-001.jpg, photo-002.jpg ...
n=1; for f in *.JPG; do mv -n -- "$f" "$(printf 'photo-%03d.jpg' "$n")"; n=$((n+1)); done

Patterns are case-sensitive: *.txt did not match Report.TXT in our test. If nothing matches a pattern, bash passes the pattern itself and mv reports cannot stat '* *'; nothing is changed.

2. The Perl rename command (Ubuntu, Debian, Linux Mint)

Install it with sudo apt install rename. It takes a Perl expression and a list of files. Always try -n first:

$ rename -n 's/\.txt$/.md/' *.txt
rename(Old Notes.txt, Old Notes.md)
rename(a.txt, a.md)
rename(b.txt, b.md)

If the list looks right, run it again with -v instead of -n. More examples:

rename -v 's/ /_/g' *          # spaces to underscores
rename -v 's/^/2026-/' *.txt   # add a prefix
rename -v '$_ = lc' *          # all names to lowercase
rename -v '$_ = uc' *          # all names to uppercase

It never overwrites a file. When File.txt and file.txt both existed, it printed File.txt not renamed: file.txt already exists and left both alone.

3. The util-linux rename command (AlmaLinux, Rocky Linux, RHEL, Fedora)

Here the syntax is rename FROM TO FILES: it replaces the first match of plain text, not a regular expression. On a minimal system it may need sudo dnf install util-linux.

$ rename -nv .txt .md *.txt
`Old Notes.txt' -> `Old Notes.md'
`a.txt' -> `a.md'
`b.txt' -> `b.md'

Drop the n to rename for real. Add -a to replace every match instead of the first (rename -av ' ' _ *), and use an empty FROM to add a prefix (rename -v '' 'img-' *.jpg). This version cannot change upper case to lower case, so use the bash method in section 4 for that.

4. Rename all files and folders to lowercase, including subfolders

Use find with -depth, so the contents of a folder are renamed before the folder itself. Otherwise find would look for files inside a folder that has just changed its name.

Ubuntu, Debian and Mint (Perl rename):

cd /path/to/dir
find . -depth -name '*[[:upper:]]*' -execdir rename -v '$_ = lc' {} +

Part of our output:

./Report.TXT renamed as ./report.txt
./Docs renamed as ./docs
./Beach View.JPG renamed as ./beach view.jpg
./Holiday 2026 renamed as ./holiday 2026
./Photos renamed as ./photos

Any distribution (bash and mv, tested on AlmaLinux 10 and Ubuntu):

cd /path/to/dir
find . -depth -name '*[[:upper:]]*' -exec bash -c 'for p; do b=${p##*/}; mv -n -- "$p" "${p%/*}/${b,,}"; done' _ {} +

${b,,} is bash for “b in lowercase”. Only the last part of each path changes, so folder names further up are never touched twice. To rename files only and keep folder names, add -type f after find ..

Two files whose names differ only in case (File.txt and file.txt) cannot both become file.txt. mv -n skips the second one: GNU coreutils 9.4 on Ubuntu 24.04 printed mv: not replacing 'file.txt', while 9.7 on Ubuntu 26.04 skipped it silently. Check for leftovers afterwards with find . -name '*[[:upper:]]*'.

A reusable script

The older script on this page split names at spaces. This version handles spaces and takes the folder as an argument:

#!/bin/bash
# lowercase.sh: rename all files and folders under DIR to lowercase
dir="${1:?Usage: lowercase.sh DIR}"
find "$dir" -mindepth 1 -depth -name '*[[:upper:]]*' -exec bash -c '
  for p; do
    b=${p##*/}
    mv -n -v -- "$p" "${p%/*}/${b,,}"
  done' _ {} +

Save it, run chmod +x lowercase.sh, then ./lowercase.sh Files. -mindepth 1 leaves the folder you name unchanged.

The old one-liner find Files -depth | xargs -n 1 rename ... also fails on spaces: in our test it reported Can't rename t/Old t/old: No such file or directory for a file called Old Notes.txt. Use the commands above instead.

Related: rename multiple folders from the command line and practical find command examples.

Official documentation: Perl rename manual and util-linux rename manual.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Managed dedicated servers

our engineers look after the server for you, from $135 a month.

Was this answer helpful?

Still stuck? Open a ticket