mv moves files and directories, and it’s also how you rename them. Linux has no separate rename command for single files. Renaming is just moving to a new name in the same place.

mv [options] SOURCE DEST
mv [options] SOURCE... DIRECTORY

Rename a file or directory

mv report.txt report-2026.txt
mv old-project new-project

Directories don’t need -r with mv, unlike cp and rm.

Move files

mv report.txt ~/archive/                 # into a directory, keeps the name
mv report.txt ~/archive/q3-report.txt    # move and rename at once
mv *.log /var/log/old/                   # many files with a glob
mv a.txt b.txt c.txt /srv/files/

When there is more than one source, the last argument must be an existing directory.

Moving a directory into an existing directory

mv site /var/www/
  • If /var/www/site doesn’t exist, site becomes /var/www/site.
  • If /var/www/site already exists and is empty, it gets replaced.
  • If it exists and isn’t empty, mv fails with “Directory not empty”. It won’t merge directories. To merge, use rsync -a src/ dest/ and then remove the source, or cp -a and then rm.

Avoid overwriting files

By default, mv silently overwrites an existing destination file. Use these options to protect yourself:

mv -i file dest          # ask before overwriting
mv -n file dest          # never overwrite (no-clobber)
mv -u file dest          # only move if the source is newer
mv --backup=numbered file dest   # keep the old dest as dest.~1~
mv -b file dest          # simple backup: dest~

In scripts, -n is a safe default when collisions are possible. -v (verbose) prints each move:

mv -v *.jpg photos/

Same filesystem vs another filesystem

Within one filesystem, mv just renames a directory entry. It’s instant even for huge files, and ownership and permissions don’t change.

Across filesystems (another disk, partition or mount), mv copies and then deletes. That takes time, and if it’s interrupted you may end up with a partial copy. For large moves to another disk, it’s safer to use:

rsync -a --remove-source-files /data/old/ /mnt/new/

and then remove the empty directories. See rsync examples.

Files with awkward names

mv -- -weird-name.txt normal.txt      # names starting with a dash
mv "my file.txt" my-file.txt          # spaces: quote the name
mv my\ file.txt my-file.txt           # or escape the space

-- tells mv that options have ended.

Bulk renaming

A loop in Bash:

# change .jpeg to .jpg
for f in *.jpeg; do mv -n -- "$f" "${f%.jpeg}.jpg"; done

# add a prefix
for f in *.png; do mv -n -- "$f" "2026-$f"; done

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

For more complex patterns, use the rename utility. On Debian/Ubuntu, apt install rename gives the Perl version:

rename -n 's/\.jpeg$/.jpg/' *.jpeg     # -n = dry run, shows what would happen
rename 's/\.jpeg$/.jpg/' *.jpeg
rename 'y/A-Z/a-z/' *                  # lowercase filenames

Always run with -n first. Note that RHEL’s rename is a different, simpler tool (rename .jpeg .jpg *.jpeg).

Moving files a service uses

  • Log files: if you mv a log that a process is writing to, the process keeps writing to the moved file, because it has the file open. That’s how log rotation works. Signal or reload the service so it reopens the log.
  • Web roots and configs: moving files keeps their ownership, but with SELinux the security label comes along too. Run restorecon -R after moving files into web directories on RHEL-family systems.

Common mistakes

  • Typo in the destination directory: mv file /srv/fils renames file to /srv/fils instead of moving it into /srv/files/. Add a trailing slash, as in mv file /srv/files/. Then mv fails if the directory doesn’t exist.
  • Overwriting by accident, for example mv config.php config.php.bak when the .bak already held the only good copy. Use -i or -n.
  • Globs that match nothing: mv *.tmp old/ with no .tmp files fails with “cannot stat ‘*.tmp’”. That’s harmless, but scripts should handle it.

Quick reference

Task Command
Rename mv old new
Move into dir mv file dir/
Ask before overwrite mv -i
Never overwrite mv -n
Verbose mv -v
Keep backup of target mv --backup=numbered
Bulk rename rename -n 's/a/b/' *

Related: cp, rm and find.

  • Linux
  • Command Line
  • Basics