]> git.deb.at Git - pkg/mmv.git/blob - mmv.1
4c707a3dbb2d975147b0dfe116e7ce96a68be539
[pkg/mmv.git] / mmv.1
1 .\" Under BSD, just give to nroff or troff (with -man).
2 .\" To print the MS-DOS version, use option -rO2.
3 .\" Under System V, take out the '.\"  ' from the next line.
4 .\" .nr O 1
5 .TH MMV 1 "November 20, 2001 (v1.0lfs)"
6 .ie !'\nO'2' \{\
7 .SH NAME
8 mmv \- move/copy/append/link multiple files by wildcard patterns
9 \}
10 .el \{
11 .SH NAME
12 mmv \- move/copy/append multiple files by wildcard patterns
13 \}
14 .ie '\nO'2' \{\
15 .ds SL \\\\
16 .ds ES '
17 \}
18 .el \{\
19 .ds SL /
20 .ds ES \\\\
21 \}
22 .SH SYNOPSIS
23 .B mmv
24 .if '\nO'2' [\fB-m\fP|\fBx\fP|\fBr\fP|\fBc\fP|\fBo\fP|\fBa\fP|\fBz\fP]
25 .if '\nO'0' [\fB-m\fP|\fBx\fP|\fBr\fP|\fBc\fP|\fBo\fP|\fBa\fP|\fBl\fP|\fBs\fP]
26 .if '\nO'1' [\fB-m\fP|\fBx\fP|\fBr\fP|\fBc\fP|\fBo\fP|\fBa\fP|\fBl\fP]
27 [\fB-h\fP]
28 [\fB-d\fP|\fBp\fP]
29 [\fB-g\fP|\fBt\fP]
30 [\fB-v\fP|\fBn\fP]
31 [\fB--\fP]
32 [\fBfrom to\fP]
33 .if '\nO'2' \{\
34 .br
35 .B mmvpatch
36 [\fBexecutable\fP]
37 \}
38 .SH "DESCRIPTION"
39 .I Mmv
40 moves (or copies,
41 .ie '\nO'2' or appends,
42 .el appends, or links,
43 as specified)
44 each source file matching a
45 .I from
46 pattern to the target name specified by the
47 .I to
48 pattern.
49 This multiple action is performed safely,
50 i.e. without any unexpected deletion of files
51 due to collisions of target names with existing filenames
52 or with other target names.
53 Furthermore, before doing anything,
54 .I mmv
55 attempts to detect any errors that would result
56 from the entire set of actions specified
57 and gives the user the choice of either
58 proceeding by avoiding the offending parts
59 or aborting.
60 .I mmv does support large files (LFS) but it does *NOT* support 
61 sparse files (i.e. it explodes them).
62 .ce
63 The Task Options
64 .PP
65 Whether
66 .I mmv
67 moves, copies,
68 .ie '\nO'2' or appends
69 .el appends, or links
70 is governed by the first set of options given
71 above.
72 If none of these are specified,
73 .ie '\nO'2' \{\
74 a default (patchable by
75 .IR mmvpatch ,
76 and initially -x)
77 determines the task.
78 \}
79 .el \{\
80 the task is given by the command name under which
81 .I mmv
82 was invoked (argv[0]):
83
84         command name    default task
85
86         mmv                     -x
87 .br
88         mcp                     -c
89 .br
90         mad                     -a
91 .br
92         mln                     -l
93 \}
94 .PP
95 The task option choices are:
96 .TP
97 -m :
98 move source file to target name.
99 Both must be on the same device.
100 Will not move directories.
101 .if '\nO'0' \{\
102 If the source file is a symbolic link,
103 moves the link without checking if the link's target from the new
104 directory is different than the old.
105 \}
106 .TP
107 -x :
108 same as -m, except cross-device moves are done
109 by copying, then deleting source.
110 When copying, sets the
111 .ie !'\nO'2' permission bits
112 .el attributes
113 and file modification time
114 of the target file to that of the source file.
115 .TP
116 -r :
117 rename source file or directory to target name.
118 The target name must not include a path:
119 the file remains in the same directory in all cases.
120 This option is the only way of renaming directories under
121 .IR mmv .
122 .if '\nO'2' It is only available under DOS version 3.0 or higher.
123 .TP
124 -c :
125 copy source file to target name.
126 Sets the file modification time and
127 .ie !'\nO'2' permission bits
128 .el attributes
129 of the target file to that of the source file,
130 regardless of whether the target file already exists.
131 Chains and cycles (to be explained below) are not allowed.
132 .TP
133 -o :
134 overwrite target name with source file.
135 .ie '\nO'2' \{\
136 If target file exists, its attributes are left unchanged.
137 If not, it is created with ordinary attributes
138 unrelated to the source file's attributes.
139 In either case, the file modification time is set to the current time.
140 \}
141 .el \{\
142 If target file exists, it is overwritten,
143 keeping its original owner and permission bits.
144 If it does not exist, it is created, with read-write permission bits
145 set according to
146 .IR umask (1),
147 and the execute permission bits copied from the source file.
148 In either case, the file modification time is set to the current time.
149 \}
150 .TP
151 -a :
152 append contents of source file to target name.
153 Target file modification time is set to the current time.
154 If target file does not exist,
155 it is created with
156 .ie '\nO'2' attributes
157 .el permission bits
158 set as under -o.
159 Unlike all other options, -a allows multiple source files to have the
160 same target name, e.g. "mmv -a
161 .ie '\nO'2' *.c
162 .el \\*.c
163 big" will append all ".c" files to "big".
164 Chains and cycles are also allowed, so "mmv -a f f" will double up "f".
165 .ie '\nO'2' \{\
166 .TP
167 -z :
168 same as -a, but if the target file exists, and its last character is a ^Z,
169 and the source file is not empty,
170 this ^Z is truncated before doing the append.
171 \}
172 .el \{\
173 .TP
174 -l :
175 link target name to source file.
176 Both must be on the same device,
177 and the source must not be a directory.
178 Chains and cycles are not allowed.
179 .if '\nO'0' \{\
180 .TP
181 -s :
182 same as -l, but use symbolic links instead of hard links.
183 For the resulting link to aim back at the source,
184 either the source name must begin with a '/',
185 or the target must reside in either the current or the source directory.
186 If none of these conditions are met, the link is refused.
187 However, source and target can reside on different devices,
188 and the source can be a directory.
189 \}
190 \}
191 .PP
192 Only one of these option may be given,
193 and it applies to all matching files.
194 Remaining options need not be given separately,
195 i.e. "mmv -mk" is allowed.
196
197 .ce
198 Multiple Pattern Pairs
199 .PP
200 Multiple
201 .I from
202 --
203 .I to
204 pattern pairs may be specified by omitting
205 the pattern pair on the command line,
206 and entering them on the standard input,
207 one pair per line.
208 (If a pattern pair is given on the command line,
209 the standard input is not read.)
210 Thus,
211
212 .in +3
213 mmv
214 .br
215 a b
216 .br
217 c d
218 .in -3
219
220 would rename "a" to "b" and "c" to "d".
221 If a file can be matched to several of the given
222 .I from
223 patterns,
224 the
225 .I to
226 pattern of the first matching pair is used.
227 Thus,
228
229 .in +3
230 mmv
231 .br
232 a b
233 .br
234 a c
235 .in -3
236
237 would give the error message "a -> c : no match" because file "a"
238 (even if it exists)
239 was already matched by the first pattern pair.
240
241 .ce
242 The \fIFrom\fP Pattern
243 .PP
244 The
245 .I from
246 pattern is a filename
247 with embedded wildcards: '*', '?', '['...']',
248 .if '\nO'2' \{\
249 \'!',
250 \}
251 and ';'.
252 The first three have their usual
253 .IR sh (1)
254 meanings of, respectively,
255 matching any string of characters,
256 matching any single character,
257 and matching any one of a set of characters.
258 .PP
259 Between the '[' and ']', a range from character 'a' through character 'z'
260 is specified with "a-z".
261 The set of matching characters can be negated by inserting
262 a '^' after the '['.
263 Thus, "[^b-e2-5_]"
264 will match any character but 'b' through 'e', '2' through '5', and '_'.
265 .if '\nO'2' \{\
266 .PP
267 Unlike DOS wildcards,
268 all mmv wildcards (except for cases listed below)
269 can occur anywhere in the pattern,
270 whether preceding or following explicit characters or other wildcards.
271 For example, the pattern "*z\\foo.bar" will search
272 for files named "foo.bar" in all subdirectories whose names end in 'z'.
273 However, no wildcards can occur in the drive letter.
274 .PP
275 The character '.' is not matched by any of '*', '?', or '['...']'.
276 Thus, the pattern "*" will only match files with a null extension.
277 To save yourself some typing, use the '!' wildcard instead,
278 which matches the same as "*.*",
279 except it is assigned only one wildcard index (see below).
280 Thus, both "f!" and "f*.*"
281 will match all of "f", "f.ext", "foo", and "foo.ext",
282 while "f*" will match only the first and the third.
283 \}
284 .PP
285 Note that paths are allowed in the patterns,
286 and wildcards may be intermingled with slashes arbitrarily.
287 The ';' wildcard
288 is useful for matching files at any depth in the directory tree.
289 It matches the same as "*\*(SL" repeated any number of times, including zero,
290 and can only occur either at the beginning of the pattern
291 or following a '\*(SL'.
292 Thus ";*.c" will match all ".c" files in or below the current directory,
293 while "\*(SL;*.c" will match them anywhere on the file system.
294 .if !'\nO'2' \{\
295 .PP
296 In addition, if the
297 .I from
298 pattern
299 (or the
300 .I to
301 pattern)
302 begins with "~/", the '~' is replaced with the home directory name.
303 (Note that the "~user" feature of
304 .IR csh (1)
305 is not implemented.)
306 However, the '~' is not treated as a wildcard,
307 in the sense that it is not assigned a wildcard index (see below).
308 \}
309 .PP
310 Since matching a directory under a task option other than -r or -s
311 would result in an error,
312 tasks other than -r and -s
313 match directories only against completely explicit
314 .I from
315 patterns (i.e. not containing wildcards).
316 Under -r and -s, this applies only to "." and "..".
317 .PP
318 .ie '\nO'2' \{\
319 Hidden and system files are also only matched
320 against completely explicit
321 .I from
322 patterns.
323 \}
324 .el \{\
325 Files beginning with '.' are only matched against
326 .I from
327 patterns that begin with an explicit '.'.
328 \}
329 However, if -h is specified, they are matched normally.
330 .if !'\nO'2' \{\
331 .PP
332 Warning: since the shell normally expands wildcards
333 before passing the command-line arguments to
334 .IR mmv ,
335 it is usually necessary to enclose the command-line
336 .I from
337 and
338 .I to
339 patterns in quotes.
340 \}
341
342 .ce
343 The \fITo\fP Pattern
344 .PP
345 The
346 .I to
347 pattern is a filename
348 with embedded
349 .I wildcard
350 .IR indexes ,
351 where an index consists of the character '#'
352 followed by a string of digits.
353 When a source file matches a
354 .I from
355 pattern,
356 a target name for the file is constructed out of the
357 .I to
358 pattern by
359 replacing the wildcard indexes by the
360 actual characters that matched the referenced wildcards
361 in the source name.
362 Thus, if the
363 .I from
364 pattern is "abc*.*" and the
365 .I to
366 pattern is "xyz#2.#1",
367 then "abc.txt" is targeted to "xyztxt.".
368 (The first '*' matched "", and the second matched "txt".)
369 Similarly, for the pattern pair ";*.[clp]" -> "#1#3\*(SL#2",
370 "foo1\*(SLfoo2\*(SLprog.c" is targeted to "foo1\*(SLfoo2\*(SLc\*(SLprog".
371 Note that there is no '\*(SL' following the "#1" in the
372 .I to
373 pattern,
374 since the string matched by any ';' is always either empty
375 or ends in a '\*(SL'.
376 In this case, it matches "foo1\*(SLfoo2\*(SL".
377 .if !'\nO'2' \{\
378 .PP
379 To convert the string matched by a wildcard
380 to either lowercase or uppercase before embedding it in the target name,
381 insert 'l' or 'u', respectively,
382 between the '#' and the string of digits.
383 .PP
384 The
385 .I to
386 pattern,
387 like the
388 .I from
389 pattern,
390 can begin with a "~/" (see above).
391 This does not necessitate enclosing the
392 .I to
393 pattern in quotes on the command line
394 since
395 .IR csh (1)
396 expands the '~' in the exact same manner as
397 .I mmv
398 (or, in the case of
399 .IR sh (1),
400 does not expand it at all).
401 \}
402 .PP
403 For all task options other than -r, if the target name is a directory,
404 the real target name is formed by appending
405 a '\*(SL' followed by the last component
406 of the source file name.
407 For example, "mmv dir1\*(SLa dir2" will,
408 if "dir2" is indeed a directory, actually move "dir1\*(SLa" to "dir2\*(SLa".
409 However, if "dir2\*(SLa" already exists and is itself a directory,
410 this is considered an error.
411 .PP
412 To strip any character (e.g. '*', '?', or '#')
413 of its special meaning to
414 .IR mmv ,
415 as when the actual replacement name must contain the character '#',
416 precede the special character with a
417 .ie '\nO'2' \{\
418 single quote (').
419 \}
420 .el \{\
421 \'\\'
422 (and enclose the argument in quotes because of the shell).
423 \}
424 This also works to terminate a wildcard index
425 when it has to be followed by a digit in the filename, e.g. "a#1\*(ES1".
426
427 .ce
428 Chains and Cycles
429 .PP
430 A chain is a sequence of specified actions where the target name of
431 one action refers to the source file of another action.
432 For example,
433
434 mmv
435 .br
436 a b
437 .br
438 b c
439
440 specifies the chain "a" -> "b" -> "c".
441 A cycle is a chain where the last target name
442 refers back to the first source file,
443 e.g. "mmv a a".
444 .I Mmv
445 detects chains and cycles regardless of the order in which
446 their constituent actions are actually given.
447 Where allowed, i.e. in moving, renaming, and appending files,
448 chains and cycles are handled gracefully, by performing them in the proper
449 order.
450 Cycles are broken by first renaming one of the files to a temporary name
451 (or just remembering its original size when doing appends).
452
453 .ce
454 Collisions and Deletions
455 .PP
456 When any two or more matching files
457 would have to be
458 .ie '\nO'2' moved or copied
459 .el moved, copied, or linked
460 to the same target filename,
461 .I mmv
462 detects the condition as an error before performing any actions.
463 Furthermore,
464 .I mmv
465 checks if any of its actions will result
466 in the destruction of existing files.
467 If the -d (delete) option is specified,
468 all file deletions or overwrites are done silently.
469 Under -p (protect), all deletions or overwrites
470 (except those specified with "(*)" on the standard input, see below)
471 are treated as errors.
472 And if neither option is specified,
473 the user is queried about each deletion or overwrite separately.
474 (A new stream to
475 .ie '\nO'2' "\\dev\\con"
476 .el "/dev/tty"
477 is used for all interactive queries,
478 not the standard input.)
479
480 .ce
481 Error Handling
482 .PP
483 Whenever any error in the user's action specifications is detected,
484 an error message is given on the standard output,
485 and
486 .I mmv
487 proceeds to check the rest of the specified actions.
488 Once all errors are detected,
489 .I mmv
490 queries the user whether he wishes
491 to continue by avoiding the erroneous actions or to abort altogether.
492 This and all other queries may be avoided by specifying either the
493 -g (go) or -t (terminate) option.
494 The former will resolve all difficulties by avoiding the erroneous actions;
495 the latter will abort
496 .I mmv
497 if any errors are detected.
498 Specifying either of them defaults
499 .I mmv
500 to -p, unless -d is specified
501 (see above).
502 Thus, -g and -t are most useful when running
503 .I mmv
504 in the background or in
505 a shell script,
506 when interactive queries are undesirable.
507
508 .ce
509 Reports
510 .PP
511 Once the actions to be performed are determined,
512 .I mmv
513 performs them silently,
514 unless either the -v (verbose) or -n (no-execute) option is specified.
515 The former causes
516 .I mmv
517 to report each performed action
518 on the standard output as
519
520 a -> b : done.
521
522 Here, "a" and "b" would be replaced by the source and target names,
523 respectively.
524 If the action deletes the old target,
525 a "(*)" is inserted after the the target name.
526 Also, the "->" symbol is modified when a cycle has to be broken:
527 the '>' is changed to a '^' on the action prior to which the old target
528 is renamed to a temporary,
529 and the '-' is changed to a '=' on the action where the temporary is used.
530 .PP
531 Under -n, none of the actions are performed,
532 but messages like the above are printed on the standard output
533 with the ": done." omitted.
534 .PP
535 The output generated by -n can (after editing, if desired)
536 be fed back to
537 .I mmv
538 on the standard input
539 (by omitting the
540 .I from
541 --
542 .I to
543 pair on the
544 .I mmv
545 command line).
546 To facilitate this,
547 .I mmv
548 ignores lines on the standard input that look
549 like its own error and "done" messages,
550 as well as all lines beginning with white space,
551 and will accept pattern pairs with or without the intervening "->"
552 (or "-^", "=>", or "=^").
553 Lines with "(*)" after the target pattern have the effect of enabling -d
554 for the files matching this pattern only,
555 so that such deletions are done silently.
556 When feeding
557 .I mmv
558 its own output,
559 one must remember to specify again the task option (if any)
560 originally used to generate it.
561 .PP
562 Although
563 .I mmv
564 attempts to predict all mishaps prior to performing any specified actions,
565 accidents may happen.
566 For example,
567 .I mmv
568 does not check for adequate free space when copying.
569 Thus, despite all efforts,
570 it is still possible for an action to fail
571 after some others have already been done.
572 To make recovery as easy as possible,
573 .I mmv
574 reports which actions have already been done and
575 which are still to be performed
576 after such a failure occurs.
577 It then aborts, not attempting to do anything else.
578 Once the user has cleared up the problem,
579 he can feed this report back to
580 .I mmv
581 on the standard input
582 to have it complete the task.
583 (The user is queried for a file name to dump this report
584 if the standard output has not been redirected.)
585 .if '\nO'2' \{\
586
587 .ce
588 \fIMmvpatch\fP
589 .PP
590 You can customize a copy of
591 .I mmv
592 via the
593 .I mmvpatch
594 utility.
595 If you wish to change the default task option,
596 run
597 .I mmvpatch
598 on a copy of
599 .I mmv
600 named as follows:
601
602         -x, -m, -r              mmv.exe
603 .br
604         -c, -o                  mcp.exe
605 .br
606         -a, -z                  mad.exe
607 .PP
608 .I Mmvpatch
609 also determines the best way to uniquely identify directories.
610 As distributed,
611 .I mmv
612 is set to use a method that is guaranteed to work the same way
613 for all versions of DOS,
614 but is both slow
615 and unable to correctly handle drives
616 affected by the
617 .I join
618 and
619 .I subst
620 DOS commands.
621 Alternatively,
622 there is a method that is fast and correct,
623 but uses an undocumented DOS feature
624 that may not work properly under all versions of DOS.
625 (However, 2.0 and 3.3 are known to work.)
626 .I Mmv
627 does
628 .I not
629 determine the best method to use on your system
630 at run-time since this is too slow.
631 The choice is left to
632 .I mmvpatch,
633 which determines if the fast method works,
634 but also allows you to return to the slow method.
635 \}
636 .SH "EXIT STATUS"
637 .I Mmv
638 exits with status 1 if it aborts before doing anything,
639 with status 2 if it aborts due to failure after completing some of the actions,
640 and with status 0 otherwise.
641 .if !'\nO'2' \{\
642 .SH "SEE ALSO"
643 mv(1), cp(1), ln(1), umask(1)
644 \}
645 .SH "AUTHOR"
646 Vladimir Lanin
647 .br
648 lanin@csd2.nyu.edu
649 .SH "BUGS"
650 .if !'\nO'2' \{\
651 If the search pattern is not quoted,
652 the shell expands the wildcards.
653 .I Mmv
654 then (usually) gives some error message,
655 but can not determine that the lack of quotes is the cause.
656 .PP
657 \}\
658 To avoid difficulties in semantics and error checking,
659 .I mmv
660 refuses to move or create directories.