ZetCode

Linux mv Command

last modified October 23, 2026

The mv command in Linux moves and renames files and directories. Renaming is simply moving a file to a new name in the same directory. Within one file system, mv only updates directory entries, so even huge files and directory trees are moved instantly; across file systems, it copies the data and deletes the original.

The syntax is mv [options] source target or mv [options] source... directory. The examples use GNU mv from coreutils.

Renaming a file

When the target is a new name in the same directory, the file is renamed.

mv notes.txt meeting-notes.txt

The file notes.txt is now called meeting-notes.txt. Its contents, permissions, and timestamps are unchanged.

$ mv notes.txt meeting-notes.txt
$ ls
archive
meeting-notes.txt
photo1.jpg
photo2.jpg
photo3.jpg
projects
report.txt

Moving a file into a directory

When the target is an existing directory, the file is moved into it under its original name.

mv report.txt archive/

The trailing slash is optional, but it documents that the target is a directory. If archive did not exist, the command without the slash would rename the file to archive; with the slash, it fails with an error instead.

$ mv report.txt archive/
$ ls archive
report.txt

Moving multiple files

With more than one source, the last argument must be a directory.

mv photo1.jpg photo2.jpg photos/
mv *.jpg photos/

The first command moves two named files. The second uses a wildcard, which the shell expands to the remaining photo3.jpg.

$ mkdir photos
$ mv photo1.jpg photo2.jpg photos/
$ mv *.jpg photos/
$ ls photos
photo1.jpg
photo2.jpg
photo3.jpg

Moving and renaming directories

Directories are moved and renamed the same way as files; no recursive option is needed.

mv projects/website projects/blog
mv photos archive/

The first command renames a directory, and the second moves the photos directory with its contents into archive.

$ mv projects/website projects/blog
$ mv photos archive/
$ tree archive projects
archive
├── photos
│   ├── photo1.jpg
│   ├── photo2.jpg
│   └── photo3.jpg
└── report.txt
projects
└── blog

4 directories, 4 files

Verbose output

The -v option prints each move.

mv -v meeting-notes.txt archive/
mv -v archive/meeting-notes.txt archive/report.txt .

The second command moves two files back to the current directory, denoted by .. Verbose output is useful in scripts and for operations with wildcards.

$ mv -v meeting-notes.txt archive/
renamed 'meeting-notes.txt' -> 'archive/meeting-notes.txt'
$ mv -v archive/meeting-notes.txt archive/report.txt .
renamed 'archive/meeting-notes.txt' -> './meeting-notes.txt'
renamed 'archive/report.txt' -> './report.txt'

Asking before overwriting

By default, mv silently overwrites an existing target. The -i option asks for confirmation first.

mv -i draft.txt report.txt

When we answer n, nothing happens. When we answer y, the target is replaced. Many users define alias mv='mv -i' in their ~/.bashrc as a safety net.

$ echo "new draft" > draft.txt
$ mv -i draft.txt report.txt
mv: overwrite 'report.txt'? n
$ cat report.txt
Q3 results
$ mv -i draft.txt report.txt
mv: overwrite 'report.txt'? y
$ cat report.txt
new draft

Never overwriting

The -n option (no-clobber) skips files whose target already exists.

mv -n config.ini config.bak

The existing config.bak keeps its contents, and config.ini stays in place. Unlike -i, this option never asks, which makes it suitable for scripts. If both -i and -n are given, the last one wins.

$ echo "v2" > config.ini; echo "v1" > config.bak
$ mv -n config.ini config.bak
$ cat config.bak
v1
$ ls config.*
config.bak
config.ini

Making backups

The -b option backs up a target file before it is overwritten.

mv -b new.log app.log
mv --backup=numbered new.log app.log

A simple backup gets a tilde suffix, here app.log~; the -S option sets a different suffix. With --backup=numbered, backups are numbered, so earlier backups are never lost.

$ echo "old" > app.log; echo "new" > new.log
$ mv -b new.log app.log
$ ls app.log*
app.log
app.log~
$ cat app.log app.log~
new
old
$ echo "newer" > new.log
$ mv --backup=numbered new.log app.log
$ ls app.log*
app.log
app.log~
app.log.~1~

Moving only newer files

The -u option moves a file only if the target is missing or older than the source.

mv -u old/data.txt new/

The source file has an older modification time than the existing target, so it is not moved and remains in the old directory. This is handy for merging directories without replacing newer versions.

$ mkdir -p old new; echo "old copy" > old/data.txt; touch -d "2026-01-01" old/data.txt; echo "new copy" > new/data.txt
$ mv -u old/data.txt new/
$ cat new/data.txt
new copy
$ ls old
data.txt

Specifying the target first

The -t option names the target directory before the sources, which suits commands that append arguments at the end.

find . -maxdepth 1 -name "*.log" -print0 | xargs -0 mv -t logs/

xargs appends the file names found by find to the command line, so the directory must come first. The -print0 and -0 options handle file names with spaces safely.

$ mkdir logs; touch a.log b.log c.log
$ find . -maxdepth 1 -name "*.log" -print0 | xargs -0 mv -t logs/
$ ls logs
a.log
b.log
c.log

Renaming many files

mv renames one file at a time, so batch renaming is done with a shell loop.

for f in *.htm; do mv -- "$f" "${f%.htm}.html"; done

The ${f%.htm} expansion removes the .htm suffix, and we append .html. The quotes protect names with spaces, and -- ends option processing, so names starting with a dash are not taken for options. Some distributions also ship a rename utility for pattern-based renaming.

$ touch page1.htm page2.htm page3.htm
$ for f in *.htm; do mv -- "$f" "${f%.htm}.html"; done
$ ls *.html
page1.html
page2.html
page3.html

Common errors

mv reports missing sources, impossible moves, and permission problems.

mv missing.txt archive/
mv archive archive/photos/
mv report.txt /etc/

A directory cannot be moved into its own subdirectory. Moving a file requires write permission on both the source and the target directory; the permissions of the file itself do not matter.

$ mv missing.txt archive/
mv: cannot stat 'missing.txt': No such file or directory
$ mv archive archive/photos/
mv: cannot move 'archive' to a subdirectory of itself, 'archive/photos/archive'
$ mv report.txt /etc/
mv: cannot create regular file '/etc/report.txt': Permission denied

Best practices for mv

Source

GNU mv manual

In this article, we have used the mv command to rename and move files and directories, avoid overwriting files, make backups, and rename files in bulk.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.