.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.49.1.
.TH MMV "1" "March 2022" "mmv 2.3" "User Commands"
.SH NAME
mmv - move/copy/link multiple files by wildcard patterns
.SH SYNOPSIS
.B mmv
[\fI\,-m|-x|-r|-c|-o|-a|-l|-s\/\fR] [\fI\,-h\/\fR] [\fI\,-d|-p\/\fR] [\fI\,-g|-t\/\fR] [\fI\,-v|-n\/\fR] \fI\,FROM TO\/\fR
.SH DESCRIPTION
move/copy/link multiple files by wildcard patterns
.PP
The FROM pattern is a shell glob pattern, in which `*' stands for any number
of characters and `?' stands for a single character.
.PP
Use #[l|u]N in the TO pattern to get the string matched by the Nth
FROM pattern wildcard [lowercased|uppercased].
.PP
Patterns should be quoted on the command line.
.TP
\fB\-\-help\fR
Print help and exit
.TP
\fB\-V\fR, \fB\-\-version\fR
Print version and exit
.TP
\fB\-h\fR, \fB\-\-hidden\fR
treat dot files normally  (default=off)
.TP
\fB\-m\fR, \fB\-\-move\fR
move source file to target name
.TP
\fB\-x\fR, \fB\-\-copydel\fR
copy source to target, then delete source
.TP
\fB\-r\fR, \fB\-\-rename\fR
rename source to target in same directory
.TP
\fB\-c\fR, \fB\-\-copy\fR
copy source to target, preserving source permissions
.TP
\fB\-o\fR, \fB\-\-overwrite\fR
overwrite target with source, preserving target permissions
.TP
\fB\-l\fR, \fB\-\-hardlink\fR
link target name to source file
.TP
\fB\-s\fR, \fB\-\-symlink\fR
symlink target name to source file
.TP
\fB\-d\fR, \fB\-\-force\fR
perform file deletes and overwrites without confirmation
.TP
\fB\-p\fR, \fB\-\-protect\fR
treat file deletes and overwrites as errors
.TP
\fB\-g\fR, \fB\-\-go\fR
skip any erroneous actions
.TP
\fB\-t\fR, \fB\-\-terminate\fR
erroneous actions are treated as errors
.TP
\fB\-v\fR, \fB\-\-verbose\fR
report all actions performed
.TP
\fB\-n\fR, \fB\-\-dryrun\fR
only report which actions would be performed
.PP
.I Mmv
moves (or copies or links, as specified)
each source file matching a
.I from
pattern to the target name specified by the
.I to
pattern.
This multiple action is performed safely,
i.e. without any unexpected deletion of files
due to collisions of target names with existing filenames
or with other target names.
Furthermore, before doing anything,
.I mmv
attempts to detect any errors that would result
from the entire set of actions specified
and gives the user the choice of either
proceeding by avoiding the offending parts
or aborting.
.I mmv
does support large files (LFS) but it does \fInot\fR support
sparse files (i.e. it explodes them).
.PP
Older versions of
.I mmv
supported interactive editing of the rename etc. operations, but using a
fragile system that could not cope with certain characters, such as spaces,
in filenames. Users who require this functionality can use
.IR qmv (1)
and friends (in the
.I renameutils
package).

.ce
The Task Options
.PP
Whether
.I mmv
moves, copies, or links
is governed by the first set of options given
above.
If none of these are specified,
the task is given by the command name under which
.I mmv
was invoked:

        command name	default task

        mmv			\-\-copydel
.br
        mcp			\-\-copy
.br
        mln			\-\-hardlink
.PP
The task option choices are:
.TP
\fB\-\-move\fR:
move source file to target name.
Both must be on the same device.
If the source file is a symbolic link,
moves the link without checking if the link's target from the new
directory is different than the old.
.TP
\fB\-\-copydel\fR:
same as \-\-move, except cross-device moves are done
by copying, then deleting source.
When copying, sets the permission bits
and file modification time
of the target file to that of the source file.
.TP
\fB\-\-rename\fR:
rename source file or directory to target name.
The target name must not include a path:
the file remains in the same directory in all cases.
.TP
\fB\-\-copy\fR:
copy source file to target name.
Sets the file modification time and permission bits
of the target file to that of the source file,
regardless of whether the target file already exists.
Chains and cycles (to be explained below) are not allowed.
.TP
\fB\-\-overwrite\fR:
overwrite target name with source file.
If target file exists, it is overwritten,
keeping its original owner and permission bits.
If it does not exist, it is created, with read-write permission bits
set according to
.IR umask (1),
and the execute permission bits copied from the source file.
In either case, the file modification time is set to the current time.
.TP
\fB\-\-hardlink\fR:
link target name to source file.
Both must be on the same device,
and the source must not be a directory.
Chains and cycles are not allowed.
.TP
\fB\-\-symlink\fR:
same as \-\-hardlink, but use symbolic links instead of hard links.
For the resulting link to aim back at the source,
either the source name must begin with a '/',
or the target must reside in either the current or the source directory.
If none of these conditions are met, the link is refused.
However, source and target can reside on different devices,
and the source can be a directory.
.PP
Only one of these options may be given,
and it applies to all matching files.

.ce
The \fIFrom\fP Pattern
.PP
The
.I from
pattern is a filename
with embedded wildcards: '*', '?', '['...']',
and ';'.
The first three have their usual
.IR sh (1)
meanings of, respectively,
matching any string of characters,
matching any single character,
and matching any one of a set of characters.
.PP
Between the '[' and ']', a range from character 'a' through character 'z'
is specified with "a\-z".
The set of matching characters can be negated by inserting
a '^' after the '['.
Thus, "[^b\-e2\-5_]"
will match any character but 'b' through 'e', '2' through '5', and '_'.
.PP
Note that paths are allowed in the patterns,
and wildcards may be intermingled with slashes arbitrarily.
The ';' wildcard
is useful for matching files at any depth in the directory tree.
It matches the same as "*/" repeated any number of times, including zero,
and can only occur either at the beginning of the pattern
or following a '/'.
Thus ";*.c" will match all ".c" files in or below the current directory,
while "/;*.c" will match them anywhere on the file system.
.PP
In addition, if the
.I from
pattern
(or the
.I to
pattern)
begins with "~/", the '~' is replaced with the home directory name.
(Note that the "~user" feature of
.IR csh (1)
is not implemented.)
However, the '~' is not treated as a wildcard,
in the sense that it is not assigned a wildcard index (see below).
.PP
The directories "." and ".." are only matched against completely explicit
.I from
patterns (i.e. not containing wildcards).
.PP
Files beginning with '.' are only matched against
.I from
patterns that begin with an explicit '.'.
However, if \-h is specified, they are matched normally.
.PP
Warning: since the shell normally expands wildcards
before passing the command-line arguments to
.IR mmv ,
it is usually necessary to enclose the command-line
.I from
and
.I to
patterns in quotes.

.ce
The \fITo\fP Pattern
.PP
The
.I to
pattern is a filename
with embedded
.I wildcard
.IR indexes ,
where an index consists of the character '#'
followed by a string of digits.
When a source file matches a
.I from
pattern,
a target name for the file is constructed out of the
.I to
pattern by
replacing the wildcard indexes by the
actual characters that matched the referenced wildcards
in the source name.
Thus, if the
.I from
pattern is "abc*.*" and the
.I to
pattern is "xyz#2.#1",
then "abc.txt" is targeted to "xyztxt.".
(The first '*' matched "", and the second matched "txt".)
Similarly, for the pattern pair ";*.[clp]" \-> "#1#3/#2",
"foo1/foo2/prog.c" is targeted to "foo1/foo2/c/prog".
Note that there is no '/' following the "#1" in the
.I to
pattern,
since the string matched by any ';' is always either empty
or ends in a '/'.
In this case, it matches "foo1/foo2/".
.PP
To convert the string matched by a wildcard
to either lowercase or uppercase before embedding it in the target name,
insert 'l' or 'u', respectively,
between the '#' and the string of digits.
.PP
The
.I to
pattern,
like the
.I from
pattern,
can begin with a "~/" (see above).
This does not necessitate enclosing the
.I to
pattern in quotes on the command line
since
.IR csh (1)
expands the '~' in the exact same manner as
.I mmv
(or, in the case of
.IR sh (1),
does not expand it at all).
.PP
For all task options other than \-r, if the target name is a directory,
the real target name is formed by appending
a '/' followed by the last component
of the source file name.
For example, "mmv dir1/a dir2" will,
if "dir2" is indeed a directory, actually move "dir1/a" to "dir2/a".
However, if "dir2/a" already exists and is itself a directory,
this is considered an error.
.PP
To strip any character (e.g. '*', '?', or '#')
of its special meaning to
.IR mmv ,
as when the actual replacement name must contain the character '#',
precede the special character with a '\\'
(and enclose the argument in quotes because of the shell).
This also works to terminate a wildcard index
when it has to be followed by a digit in the filename, e.g. "a#1\\1".

.ce
Chains and Cycles
.PP
A chain is a sequence of specified actions where the target name of
one action refers to the source file of another action.
For example,

mmv
.br
a b
.br
b c

specifies the chain "a" \-> "b" \-> "c".
A cycle is a chain where the last target name
refers back to the first source file,
e.g. "mmv a a".
.I Mmv
detects chains and cycles regardless of the order in which
their constituent actions are actually given.
Where allowed, i.e. in moving and renaming files,
chains and cycles are handled gracefully, by performing them in the proper
order.
Cycles are broken by first renaming one of the files to a temporary name.

.ce
Collisions and Deletions
.PP
When any two or more matching files
would have to be moved, copied, or linked
to the same target filename,
.I mmv
detects the condition as an error before performing any actions.
Furthermore,
.I mmv
checks if any of its actions will result
in the destruction of existing files.
If the \-d (delete) option is specified,
all file deletions or overwrites are done silently.
Under \-p (protect), all deletions or overwrites
(except those specified with "(*)" on the standard input, see below)
are treated as errors.
And if neither option is specified,
the user is queried about each deletion or overwrite separately.
(The terminal is used for interactive queries,
not standard input.)

.ce
Error Handling
.PP
Whenever any error in the user's action specifications is detected,
an error message is given on the standard output,
and
.I mmv
proceeds to check the rest of the specified actions.
Once all errors are detected,
.I mmv
asks the user whether to continue by avoiding the erroneous actions or to abort altogether.
This and all other queries may be avoided by specifying either the
\-g (go) or \-t (terminate) option.
The former will resolve all difficulties by avoiding the erroneous actions;
the latter will abort
.I mmv
if any errors are detected.
Specifying either of them defaults
.I mmv
to \-p, unless \-d is specified
(see above).
Thus, \-g and \-t are most useful when running
.I mmv
in the background or in
a shell script,
when interactive queries are undesirable.

.ce
Reports
.PP
Once the actions to be performed are determined,
.I mmv
performs them silently,
unless either the \-v (verbose) or \-n (no-execute) option is specified.
The former causes
.I mmv
to report each performed action
on the standard output as

a \-> b : done.

Here, "a" and "b" would be replaced by the source and target names,
respectively.
If the action deletes the old target,
a "(*)" is inserted after the the target name.
Also, the "\->" symbol is modified when a cycle has to be broken:
the '>' is changed to a '^' on the action prior to which the old target
is renamed to a temporary,
and the '\-' is changed to a '=' on the action where the temporary is used.
.PP
Under \-n, none of the actions are performed,
but messages like the above are printed on the standard output
with the ": done." omitted.
.PP
Although
.I mmv
attempts to predict all mishaps prior to performing any specified actions,
accidents may happen.
For example,
.I mmv
does not check for adequate free space when copying.
Thus, despite all efforts,
it is still possible for an action to fail
after some others have already been done.
To make recovery as easy as possible,
.I mmv
reports which actions have already been done and
which are still to be performed
after such a failure occurs.
It then aborts, not attempting to do anything else.
.SH "EXAMPLES"
Rename all
.I *.jpeg
files in the current directory to
\fI*.jpg\fR:

.in +3
mmv '*.jpeg' '#1.jpg'
.in -3

Replace the first occurrence of
.I abc
with
.I xyz
in all files in the current directory:

.in +3
mmv '*abc*' '#1xyz#2'
.in -3

Rename files ending in \fI.html.en\fR, \fI.html.de\fR, etc. to ending
in \fI.en.html\fR, \fI.de.html\fR, etc. in the current directory:

.in +3
mmv '*.html.??' '#1.#2#3.html'
.in -3

Rename music files from
.I <track no.> - <interpreter> - <song title>.ogg
to
.I <interpreter> - <track no.> - <song title>.ogg
in the current directory:

.in +3
mmv '* - * - *.ogg' '#2 - #1 - #3.ogg'
.in -3

.SH "EXIT STATUS"
.I Mmv
exits with status 1 if it aborts before doing anything,
with status 2 if it aborts due to failure after completing some of the actions,
and with status 0 otherwise.
.SH "SEE ALSO"
mv(1), cp(1), ln(1), umask(1), qmv(1), qcp(1), imv(1), icp(1)
.SH "AUTHOR"
Written by Vladimir Lanin and Reuben Thomas.
.SH "BUGS"
If the search pattern is not quoted,
the shell expands the wildcards.
.I Mmv
then (usually) gives some error message,
but can not determine that the lack of quotes is the cause.
.PP
To avoid difficulties in semantics and error checking,
.I mmv
refuses to create directories.
.SH COPYRIGHT
Copyright \(co 2022 Reuben Thomas <rrt@sc3d.org>
.br
Copyright \(co 1990 Vladimir Lanin.
Licence GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.