Can you use wildcards in a similar way, that works for a scenario like the above?
Not like ebook-convert *epub *mobi
, because of how wildcards - really "shell globbing" - works. But, you can get started with a wildcard.
Shell globbing is, conceptually, very straightforward: find all of the files that match the glob and replace the glob with that file list, handling whitespace and other "special" characters so that the invoked action (often a program; here, ebook-convert
) gets each file as a single, separate parameter.
So, given a folder with a.epub
, b.epub
, and file with spaces.epub
, the shell will expand *.epub
to a.epub
, b.epub
, and file with spaces.epub
as 3 separate arguments to whatever is being invoked (here, ebook-convert
).
Given that same folder, *.mobi
won't match anything, so ebook-convert
will receive an argument that is literally *.mobi
. From ebook-convert
's perspective, it's being given a list of three epub files and one mobi file that doesn't exist; how it handles that list of parameters is up to it (at a guess, it'll either complain about too many parameters or will sequentially try to convert each of the epubs into a mobi file literally named "*.mobi").
Note that there's no global guarantee about how a program (or shell built-in or function or script, etc.) will handle a parameter that it expects to be a file name but that contains a glob. Typically, that parameter will be treated as a string literal, and will react to *.mobi
not existing just like it would to anything_else.mobi
not existing, but there's no law that states that that has to happen.
The same thing happens for other globs; eg., ?.epub
would include a.epub
and b.epub
, but not file with spaces.epub
.
As others have noted, you can use globs to power loops - for file in *.epub ; do ...
. Note that references to "file" need to be quoted to handle spaces: the globbing in for file in *.epub
only ensures that file with spaces.epub
is a single parameter to the for
loop itself, but doesn't extend into the body of the loop (that is, for file in *.epub ; do ebook-convert $file
will send three separate parameters for file with spaces.epub
: file
, with
, and spaces.epub
).
All of this is also why you often need to quote arguments to programs that expect glob characters: doing so prevents the shell from expanding the glob and actually lets the invoked program see the argument as you wrote it. For example, find . -type f -name '*.epub'
will find (and print the names of) all epub files in this directory and any child directories; find . -type f -name *.epub
will error out since it'll see b.epub
and file with spaces.epub
as arguments with which it doesn't know what to do.
blah *.foo *.bar
, the shell just seesblah a.foo b.foo x.bar y.bar
, it doesn't know they came from distinct wildcard entries on the original command line. And if nothing matching*.bar
exists, well, depending on the settings, that pattern is left as-is, removed, or causes an error.copy
in MsDOS, ignoring the way glob patterns and the command line interface work in Unix. That's like insisting to use "gift" in English with its meaning from German.