# Moving files on Linux
by Seth Kenlon

Moving files on Linux is done with the ``mv`` command.
A simple command with a predictable syntax, ``mv SOURCE DESTINATION`` moves a SOURCE file to some DESTINATION, each defined by either an [absolute](https://opensource.com/article/19/7/understanding-file-paths-and-how-use-them) or [relative](https://opensource.com/article/19/7/navigating-filesystem-relative-paths) file path.
It's such a common command for [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) users that many of its additional modifiers are generally unknown, so this article seeks to bring a few useful modifiers to the attention to both new and experienced users.

Before delving into actually moving files, though, it's worth taking a closer look at what actually happens when "moving" file system objects.
When a file is created, it is assigned to an *inode*, a fixed point in a file system used for data storage.
You can see at which inode a file is located with the [ls](https://opensource.com/article/19/7/master-ls-command) command:

```
$ ls --inode example.txt
7344977 example.txt
```

When you "move" a file, you don't actually move the data from one inode to another, you only assign the file object a new name or file path.
In fact, the permissions of a file are retained when a file is moved, because "moving" a file isn't actually changing or re-creating the file.
Inode assignment is sequential based on when the file was created, and is entirely independent of how you organize your computer.
A file "inside" a directory may have a lower inode number than its parent directory, or a higher one.
The inodes of files and directories never imply inheritance, and are dictated by the file system itself.

```
$ mkdir foo
$ mv example.txt foo
$ ls --inome
7476865 foo
$ ls --inode foo
7344977 example.txt
```

When moving a file from one hard drive to another, however, the inode is very likely to change, because new data is being written onto a new file system.

For this reason, in Linux "moving" and renaming a file are literally the same action.
Whether you move a file to another directory or to the same directory, both actions are performed by the same underlying program.
This article focuses on moving files from one directory to another.


## Moving with a mouse

The GUI is a friendly and, to most people, familiar layer of abstraction on top of a complex collection of binary data.
It's also the first and most intuitive way you can move files on Linux.
If you're used to the desktop experience, in a generic sense, then you probably already know how to move files around your hard drive.
In the GNOME desktop, for instance, the default action when dragging and dropping a file from one window to another is to move the file rather than to copy it, so it's probably one of the most intuitive actions on the desktop.

![Gnome move](gnome-mv.jpg)

The Dolphin file manager in the KDE Plasma desktop defaults to prompting the user for an action.
Holding the **Shift** key whilst dragging a file forces a move action.

![KDE move](kde-mv.jpg)


## Moving with mv

The ``mv`` command on Linux, BSD, Illumos or Solaris, and MacOS is the shell command intended for moving files.
Not all ``mv`` commands were written by the same people, though, so you may have GNU ``mv`` or BSD ``mv`` or Sun ``mv``, depending on your operating system.
Command options differ from implementation to implementation, and BSD ``mv`` has no long options at all, so refer to the man page to see what's supported, or install your preferred version (that's the luxury of open source).


### How to move a file

To move a file from one folder to another, you use the ``mv`` command.
For instance, to move the file ``example.txt`` into your ``Documents`` directory:

```
$ cp example.txt ~/Documents
```

Just like when you drag and drop a file onto a folder icon to move a file into it, this command doesn't replace ``Documents`` with ``example.txt``.
Instead, ``mv`` detects that ``Documents`` is a folder, and places the ``example.txt`` file into it.

You can also, conveniently, rename the file as you move it:

```
$ cp example.txt ~/Documents/foo.txt
```

That's important because it enables you to rename a file even when you don't want to move it to another location:

```
$ ls
example.txt
$ mv example.txt foo.txt
$ ls
foo.txt
```

### How to move a directory

The ``mv`` command doesn't differentiate a file from a directory the way the [cp](https://opensource.com/article/19/7/copying-files-linux) does.
You can move a directory or a file with the same syntax:

```
$ touch file.txt
$ mkdir foo_directory
$ mv file.txt foo_directory
$ mv foo_directory ~/Documents
```

You can also move a directory into a directory:

```
$ mkdir foo
$ mkdir bar
$ mv bar foo
```

### Moving a file safely

If you copy a file to a directory in which a file of the same name already exists, the ``mv`` command by default replaces the destination file with the one you are moving.
This is called "clobbering", and sometimes it's exactly what you intend.
Other times, it is not.

Some distributions [alias](https://opensource.com/article/19/7/bash-aliases) ``mv`` to ``mv --interactive``, which prompts you for confirmation.
Some do not.
Either way, you can use the ``--interactive`` or ``-i`` option to ensure that ``mv`` asks for confirmation in the event that two files of the same name are in conflict.

```
$ mv --interactive example.txt ~/Documents
mv: overwrite '~/Documents/example.txt'?
```

If you do not want to have to manually intervene, use ``--no-clobber`` or ``-n`` instead.
This silently rejects the move action in the event of conflict.

```
$ mv --no-clobber example.txt ~/Documents
$ ls
example.txt
```

### Moving with backups

If you're using GNU ``mv``, there are backup options offering another means of safe moving.

To create a backup of any conflicting destination file, use the ``-b`` option.

```
$ mv -b example.txt ~/Documents
$ ls ~/Documents
example.txt    example.txt~
```

This ensures that ``mv`` completes the move action, but also protects any pre-existing file in the destination location.

Another GNU backup option is ``--backup``, which takes an argument defining how the backup file is named:

* numbered: appends the destination file with a number.
* simple: appends the destination file with a ``~``, which can conveniently be hidden from your daily view with the ``--ignore-backups`` option of [ls](https://opensource.com/article/19/7/master-ls-command).
* existing: if numbered backups already exist in the destination, then a numbered backup is created. Otherwise, the simple scheme is used.
* none: does not create a backup even if ``--backup`` is set. This is useful to override a ``mv`` alias that sets the backup option.

For example:

```
$ mv --backup=numbered example.txt ~/Documents
$ ls ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:23 example.txt
-rw-rw-r--. 1 seth users 128 Aug  1 17:20 example.txt.~1~
```

A default backup scheme can be set with the environment variable ``VERSION_CONTROL``.
You can set environment variables in your ``~/.bashrc`` file or dynamically before your command:

```
$ VERSION_CONTROL=numbered mv --backup example.txt ~/Documents
$ ls ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:23 example.txt
-rw-rw-r--. 1 seth users 128 Aug  1 17:20 example.txt.~1~
-rw-rw-r--. 1 seth users 128 Aug  1 17:22 example.txt.~2~
```

The ``--backup`` option still respects the ``--interactive`` or ``-i`` option, so it still prompts you to overwrite the destination file, even though it creates a backup before doing so:

```
$ mv --backup=numbered example.txt ~/Documents
mv: overwrite '~/Documents/example.txt'? y
$ ls ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:24 example.txt
-rw-rw-r--. 1 seth users 128 Aug  1 17:20 example.txt.~1~
-rw-rw-r--. 1 seth users 128 Aug  1 17:22 example.txt.~2~
-rw-rw-r--. 1 seth users 128 Aug  1 17:23 example.txt.~3~
```

You can override ``-i`` with the ``--force`` or ``-f`` option.

```
$ mv --backup=numbered --force example.txt ~/Documents
$ ls ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:26 example.txt
-rw-rw-r--. 1 seth users 128 Aug  1 17:20 example.txt.~1~
-rw-rw-r--. 1 seth users 128 Aug  1 17:22 example.txt.~2~
-rw-rw-r--. 1 seth users 128 Aug  1 17:24 example.txt.~3~
-rw-rw-r--. 1 seth users 128 Aug  1 17:25 example.txt.~4~
```

The ``--backup`` option is not available in BSD ``mv``.


### Moving many files at once

When moving multiple files, ``mv`` treats the final directory named as the destination:

```
$ mv foo bar baz ~/Documents
$ ls ~/Documents
foo   bar   baz
```

If the final item is not a directory, ``mv`` returns an error:

```
$ mv foo bar baz
mv: target 'baz' is not a directory
```

The syntax of GNU ``mv`` is fairly flexible.
If you are unable to provide the ``mv`` command with the destination as the final argument, use the ``--target-directory`` or ``-t`` option:

```
$ mv --target-directory=~/Documents foo bar baz
$ ls ~/Documents
foo   bar   baz
```

This is especially useful when constructing ``mv`` commands from the output of some other command, such as the ``find`` command, ``xargs``, or [GNU Parallel](https://opensource.com/article/18/5/gnu-parallel).


### Moving based on mtime

With GNU ``mv``, you can define a move action based on whether the file being moved is newer than the destination file it would replace.
This is possible with the ``--update`` or ``-u`` option, and is not available in BSD ``mv``.

```
$ ls -l ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:32 example.txt
$ ls -l
-rw-rw-r--. 1 seth users 128 Aug  1 17:42 example.txt
$ mv --update example.txt ~/Documents
$ ls -l ~/Documents
-rw-rw-r--. 1 seth users 128 Aug  1 17:42 example.txt
$ ls -l
```

This is exclusively based on the modification time of the files, not on a diff of the two files, so use it with care.
It's easy to fool ``mv`` with a mere ``touch`` command:

```
$ cat example.txt
one
$ cat ~/Documents/example.txt
one
two
$ touch example.txt
$ mv --update example.txt ~/Documents
$ cat ~/Documents/example.txt
one
```

Obviously this isn't the most intelligent update function available, but it offers basic protection against overwriting recent data.


## A moving experience

There are more ways to move data than just the ``mv`` command, but as the default program for the job, ``mv`` is a good universal option.
In my [next article](LINK TO MY MOVING FILES ARTICLE), I'll discuss alternate ways of moving data from one place to another.