.Dd $Mdocdate: September 24 2023 $ .Dt MMV 1 .Os .Sh NAME .Nm mmv , .Nm mcp .Nd mapped file moves and -copies .Sh SYNOPSIS .Nm .Op Fl 0bdeinv .Ar command .Op Ar argument ... .Nm mcp .Op Fl 0bdeiv .Ar command .Op Ar argument ... .Sh DESCRIPTION The .Nm mmv and .Nm mcp utilities are tools for copying-, moving-, and renaming files by mapping filenames using a provided .Ar command and .Ar argument Ns s. When invoked, the program specified by .Ar command with the arguments .Ar argument ... is invoked to read filenames from the standard input and output new filenames to the standard output. .Nm mmv will then move all files — and .Nm mcp will then copy all files — that were provided via the standard input to their coressponding destinations which .Ar command printed to the standard output. In other words, .Ql mmv cat can be seen as a no-op. You can find a variety of examples under the .Sx EXAMPLES section. .Pp It is also very important to remember that filenames may contain newline characters. The .Fl 0 , .Fl e , and .Fl i options might be of use to help you properly handle these. .Pp The options are as follows: .Bl -tag -width Ds .It Fl 0 , Fl Fl nul Treat filenames read from the standard input as being nul-byte .Pq Sq \e0 separated instead of newline .Pq Sq \en separated. This is useful if input filenames might contain embedded newline characters. .It Fl b , Fl Fl basename Only apply the mapping command to the basenames of the given file paths. This stops you from accidentally mutating directory components, which is not typically a desired behavior. If no basename can be derived .Pq the root directory for example has no basename , then a warning diagnostic will be printed to the standard error, and the path will remain unchanged. .It Fl d , Fl Fl dry-run Print the renamings that would take place with the given inputs and arguments to the standard error without actually executing any moves. It is recommended you run .Nm mmv and .Nm mcp with this flag before performing any changes to ensure nothing unexpected occurs. .It Fl e , Fl Fl encode Encode newlines in filenames as the literal string .Sq \en and backslashes as the literal string .Sq \e\e . This will allow you to treat multi-line filenames as single-line ones. An example usecase of this is detailed in the .Sx EXAMPLES section. .It Fl i , Fl Fl individual Spawn a new instance of the command provided to .Nm mmv or .Nm mcp for each input filename. This is useful for use in conjunction with the .Fl 0 option when provided mapping command doesn’t have built-in support for nul-byte delimited input. .It Fl n , Fl Fl no-backup The default behavior of .Nm mmv is to create a backup of your input files in .Pa $XDG_CACHE_DIR/mmv to avoid dataloss in the case of an error. If for whatever reason you do not want to create this directory .Pq perhaps for performance reasons then you can use this option. .Pp This flag does not apply to .Nm mcp . .It Fl v , Fl Fl verbose Display output to the standard error detailing which files and directories are being created, moved, and removed. .El .Sh FILES .Bl -tag -width $XDG_CACHE_DIR/mmv .It Pa $XDG_CACHE_DIR/mmv The backup directory where a copy of your input files are stored during operation. Input files are backed up in a subdirectory whose name is the timestamp of when the directory was created. If the .Ev XDG_CACHE_DIR environment variable is not set, .Nm will default to using .Pa $HOME/.cache/mmv . .El .Sh EXIT STATUS .Ex -std mmv mcp .Sh EXAMPLES Swap the files .Pa foo and .Pa bar : .Pp .Dl $ ls foo bar | mmv tac .Pp Rename all files in the current directory to use hyphens .Pq Sq - instead of spaces: .Pp .Dl $ ls | mmv tr \(aq \(aq \(aq-\(aq .Pp Rename all *.jpeg files to use the .Sq .jpg file extension: .Pp .Dl $ ls *.jpeg | mmv sed \(aqs/\e.jpeg$/.jpg/\(aq .Pp Rename a given list of movies to use lowercase letters and hyphens instead of uppercase letters and spaces, and number them so that they’re properly ordered in globs .Po e.g. rename .Pa The Return of the King.mp4 to .Pa 02-the-return-of-the-king.mp4 .Pc : .Pp .Bd -literal -offset indent $ ls \(aqThe Fellowship of the Ring.mp4\(aq ... \(aqThe Two Towers.mp4\(aq | \e mmv awk \(aq{ gsub(" ", "-"); printf "%02d-%s", NR, tolower($0) }\(aq .Ed .Pp Rename files interactively in your editor while encoding newlines into the literal string .Sq \en , making use of .Xr vipe 1 from moreutils: .Pp .Dl $ ls | mmv -0e vipe .Pp Rename all C source code and header files in a git repository to use snake_case instead of camelCase using the GNU .Xr sed 1 .Ql \eL extension: .Pp .Dl $ git ls-files \(aq*.[ch]\(aq | mmv sed \(aqs/[A-Z]/\eL_&/g\(aq .Pp Lowercase all filenames within a directory hierarchy which may contain newline characters: .Pp .Dl $ find . -print0 | mmv -0 tr A-Z a-z .Pp Map filenames which may contain newlines in the current directory with the command .Ql cmd , which itself does not support nul-byte separated entries. This only works assuming your mapping doesn’t require any context outside of the given input filename .Po for example, you would not be able to number your files as this requires knowledge of the input files position in the input list .Pc : .Pp .Dl $ ls --zero | mmv -0i cmd .Pp Uppercase the files in the .Pa /foo/bar directory, while leaving the names of .Pa foo and .Pa bar unchanged: .Pp .Dl $ ls /foo/bar/* | mmv -b tr a-z A-Z .Sh SEE ALSO .Xr awk 1 , .Xr cp 1 , .Xr mv 1 , .Xr sed 1 , .Xr vipe 1 .Pp .Lk https://thomasvoss.com/prj/mmv "Extended Description and -Documentation" .Sh AUTHORS .An Thomas Voss Aq Mt mail@thomasvoss.com