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