Moving Files
Moving files is such a common/basic thing we have to do every day in Linux that you're probably wondering why I'm even bothering to write a tutorial on it. Well, there are often important subtleties that are forgotten or need to be learned. Hopefully after reading this tutorial, you will feel more comfortable using the mv
command in the CLI rather than just using cut and paste in a file manager which is often a lot slower (especially when you are dealing with codebases of hundreds/thousands of files and have .svn or .git areas).
To move file a.txt
to within a directory b
, I usually do the following:
mv a.txt b/.
However, the following will work too:
mv a.txt b/
You can even use the *
wildcard so if you wanted to move all of your files ending in .txt
, then you could do the following.
mv *.txt b/.
.
character being considered anything other than a .
character. For example a file called filertxt
would not have been moved.
If Files Already Exist
The mv
command can take the following options which tell it how to behave if the file (or some of the files) already exist at the destination.
--no-clobber
(-n)
- Don't overwrite existing files.--interactive
(-i)
- prompt before overwriting existing files.--force
(-f)
- Just overwrite the files and do not prompt.
If you use --interactive
option and choose not to overwrite a file it prompts you for, the original will not be removed after the operation finishes.
If you provide more than one of i
,f
, or n
options, then only the last will be used.
Default Behaviour
The mv
command will overwrite existing files at the destination without warning/prompting. This may make you question what is the point of having the -f
option then? Having -f
allows me to set an alias for mv
so that it will default to -i, and then I can use -f
later to have the command not prompt me. If you don't want to set an alias, then I would recommend setting the -i option just in case.
alias move="mv -i"
move
as the alias instead of overriding mv
because I don't want to forget that mv
will automatically overwrite files when I SSH into a remote server.
Moving Files Between Filesystems
When you are moving files within the same filesystem, the operation is almost instant as you are simply changing the metadata to rename the files and perhaps change some pointers etc. You are not actually moving the content of the files on the physical disk.
However, if you were to use the mv
command to move the files from one filesystem to another, (even if it is on the same disk, such as a ZFS dataset), then mv
will be moving the content and will try to copy all of the files to the destination before finishing off by deleting the originals. This means it will take a lot longer and work your storage drives. I forgot about this subtlety, so when I recently tried to move files from one ZFS dataset to another in the same pool, I ended up running out of space because mv
essentially duplicated all my files and failed to complete because it ran out of space.
Move Files One At A Time
If you need a bunch of files to be moved one at a time to prevent running out of space, then you may wish to consider using rsync
instead as shown below:
rsync \
--remove-source-files \
--recursive \
--verbose \
--human-readable \
--progress \
--links \
--copy-unsafe-links \
--owner \
--group \
--perms \
--times \
--force \
--ignore-errors \
--sparse \
--info=progress2 \
/path/to/source \
/path/to/destination
Unfortunately there is no interactive option for when the destination file already exists, so you may wish to just skip these cases by adding the --ignore-existing
parameter.
References
First published: 16th August 2018