% DOALL(1)
doall - execute a command for all files matching a pattern, with other filenames modified to match.
doall [OPTION]... 'command-in-quotes'
where command-in-quotes is a command that could be executed in the shell.
The quotes may be single or double in the usual shell manner.
They are needed to prevent the command line shell expanding wildcard sequences before doall can process them.
doall executes a command for each file matching the first filename specified using wildcard characters
in the usual way. Subsequent filenames get their wildcards replaced with the matching strings from this pattern.
A typical command might be doall "ffmpeg -i *.dv *.mp4".
If the working directory contained spring.dv, summer.dv and autumn.dv,
the commands to be executed would be:
ffmpeg -i spring.dv spring.mp4
ffmpeg -i summer.dv summer.mp4
ffmpeg -i autumn.dv autumn.mp4
doall can handle filenames containing special characters;
if the working directory contained files "b'day.dv" and 'Last Christmas.dv', the commands would be equivalent to:
ffmpeg -i b\'day.dv b\'day.mp4
ffmpeg -i Last\ Christmas.dv Last\ Christmas.mp4
doall matches using the usual shell 'globbing' wildcards in the first filename using them:
Wildcard sequences in filenames other than the first are replaced irrespective of the particular way they are spelled:
mv *.??? *.new.???
mv *.??? *.new.*
mv *.??? ????.new.????
All the above expand to the same commands; the files matched will have 3 character extensions,
as will the renamed files. The wildcards in subsequent filenames are merely placeholders for replacements.
doall does not accept patterns with a sequence of wildcards containing more than one "*".
"??*???" is fine, but "??*?*??" is not. (If it were, the first "*" would always match a null string.)
doall supports neither the [...] style of wildcards nor the alternative list {foo,bah} style of wildcards.
doall rejects patterns containing ';' characters
doall expands only what matches; it does not include path information. Thus:
doall 'mv adir/*.new */old'
moves the matching files from "adir" to the current working directory. Probably the intention was:
doall 'mv adir/*.new adir/*.old'
POSIX specifies that a wildcard never matches a "/" in a path, nor a leading '.' in a hidden filename.
Wildcards in tilde expansions such as "~*/foo" are invalid.
"/home/*/foo" will work, but may not mean the same; for example, that misses "~root/foo" on most systems.
As an alternative to wildcards, doall supports the use of shell script parameter names
$1, $2 ... in filenames.
This allows both reordering the matching strings in filenames,
and cases where the files to be processed are
not specified by the first filename in the command. See the examples.
It is also clearer in cases with adjacent "?" and " wildcards, such as "????????".
doall should be safe against most problems caused by dubious filenames, such as "foo;rm -fr *",
or containing '\n's or quotes,
because it "quotes" each word containing substitutions.
Thus the command:
doall 'cp -n *.old *.new'
acts as it were entered for each file "foo.old" as:
cp -n "foo.old" "foo.new"
One potential problem it cannot protect against is a match that (a) evaluates to a string starting with a hyphen,
and (b) is the first substitution in a filename.
Usually this combination would simply generate an invalid command option.
For example, consider the following copy command:
doall 'cp -n -t dir A*.conf $1 A$1.conf A$1.map'
which should copy files "foo" (without the "A") "Afoo.conf" and "Afoo.map" to directory "dir" for all "Afoo.conf"
files in the working directory, but preventing overwriting existing files.
However, if the working direcory contains a file "A-f.conf", the command will evaluate to
cp -n -t dir A-f.conf -f A-f.conf A-f.map
and notice how the bald "-f" will override the "-n" option.
The command passed to doall can reference enviroment variables (and indeed shell variables).
It's not possible to have multiple commands (delimited by ';'s) in the doall parameter,
because doall will quote the semicolon and therefore pass it as a parameter to the first command,
rather than treat it as a delimiter.
The wildcard expansion before executing the command uses shell "eval";
malformed parameter substitutions will be misunderstood.
Thus it is possible to use strings that represent shell expressions in the command.
For example "doall 'mv *.* $@.*'" will go haywire because "$@" will be expanded to gibberish.
Shell variable names in the command may be masked by those used within doall.
To avoid problems, either use double quotes in the command parameter,
so that the variables are expanded before doall processes the command,
or stick to UPPER CASE variable names, which doall never uses.
For example:
doall "mv $home/*.old $home/*.new"
doall 'mv $HOME/*.old $HOME/*.new'
Copyright (C) 2021 Paul Gover
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.
If not, see https://www.gnu.org/licenses/