Menu

Home

Paul Gover

% DOALL(1)

NAME

doall - execute a command for all files matching a pattern, with other filenames modified to match.

SYNOPSIS

doall OPTION... 'command-in-quotes'

where command-in-quotes is a command that could be executed in the shell.

See also

[Design choices]
[ Development]

DESCRIPTION

doall executes a command for each file matching the first filename specified using wildcard characters
in the usual way. Other 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

The command must be passed to doall in single quotes to prevent the shell prematurely expanding them.

Wildcards

doall matches using the usual shell 'globbing' wildcards in the first filename using them:

*
which matches any string including the null string
?
each of which matches exactly one character
(thus ".???" would match three letter extensions; "???" counts as one wildcard).

Wildcards 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 the target filename 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

Beware

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'

Note also that a wildcard never matches a "/" in a path, nor a leading '.' in a hidden filename; POSIX specifies this globbing behaviour.
It cannot handle wildcards in tilde expansions such as "~*/foo", which is an invalid shell glob sequence.
"/home/*/foo" will work, but may not mean the same; for example, that misses "~root/foo" on most systems.

Parameter substitution in filenames

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 "????????".

Security

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.

OPTIONS

-k
Keep going; unless set, doall will terminate after the first command with non-zero exit status.
-p, -n
Pretend mode; display the command list that would be run, but do not execute it.
-c auto|always|never
Whether to colour the listing in pretend mode.
-v, -x
Verbose mode; list each command immediately before its execution.
-i
Interactive mode; list each command before execution and request confirmation before proceeding.
-h
Displays a short help message.

ENVIRONMENT

PAGER
The program used to display the command list in pretend mode. If unset, defaults to "cat".
PS4
The line prefix sequence used for verbose output.

The command passed to doall can reference enviroment variables (and indeed shell variables).

EXAMPLES

doall 'mv *.new *.old'
Change the filename extension of a bunch of files.
doall 'ffmpeg -i *.dv *.mp4'
Compress a bunch of files grabbed from a camcorder.
doall 'mv *.* $2/$1.$2'
Move files into directories according to their filename extensions.
doall 'foobar $1.$2 *.old*'
Run foobar where the files to be processed are specified by the second parameter.
doall 'ln -s /boot/*-5.12.6-gentoo* /boot/$1.new'
Create "{vmlinuz,config,System.Map}.new" etc. symlinks for a chosen set of kernel files.
doall 'ln -s /boot/*-${KVER}* $1.new'
The same as the previous example if the KVER environment variable is set to '-5.12.6-gentoo',
as might be created using: "export KVER=$(make kernelversion)" in a kernel build directory.
doall 'mv -n ????*??? $1$3'
Abbreviate filenames of 7 or more characters to the first 4 and last 3 characters.

EXIT VALUES

0
Success
1
In "keep going" mode, one or more commands returned a non-zero exit status.
99
User answered 'quit' to prompt in interactive mode.
anything else
As set by the failing command when it terminated doall.

BUGS

doall does not allow single quote characters in the command, nor embedded spaces in patterns or filenames,
and there is no escape sequence to generate them.

The wildcard expansion before executing the command uses shell "eval";
malformed parameter substitutions will be misunderstood.
For example, 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.

LICENCE

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/


Related

Wiki: Design choices
Wiki: Development

MongoDB Logo MongoDB