Frequently, we will want to apply the same operation to multiple files. For example, we may want to move all files of a certain extension to a different folder. Rather than applying these operations one-at-a-time, most shells allow you to use a tool called a wildcard to specify multiple files at once. This allows you to set up a general template for the “type” of filename that you want to use as input (or sometimes output) to your command, and then apply the command to all files that match that template in one go.
Unfortunately, the wildcard capabilities of Command Prompt are rather limited compared to other shells. On Command Prompt, it is up to each individual command to take care of wildcards, rather than the shell taking care of it automatically (as is the case in Bash and PowerShell). However, the basic use cases for wildcards are, happily, accounted for by most of the Command Prompt commands that can take advantage of them, and so Command Prompt will be sufficient to introduce the concept. Know that what we discuss in this section is a mere taste of what is possible.
Matching all Files with a Certain Extension
Let’s consider the following situation. We have a directory that contains a variety of files of a few different types, such as the following,
We may want to create individual folders for each type of file, and move the appropriate files into the appropriate folder. Obviously, in this case, there aren’t that many files to consider. But you might well imagine a situation where we have many dozens, or even hundreds, of files that we’d like to relocate. The same principles will apply.
Let’s start by simply creating the directories we’d like to organize our files into. We’ll make one to store the C code (.c and .h), one for R code (.r), and let’s combine Python (.py) and Lua (.lua) into a directory for scripts. We can make all these new directories with one call to mkdir, like so,
Now, we can use the move command to relocate our files to the appropriate place. However, notice that we have two different .lua files. This means that we would, presumably, need to use two different commands to accomplish this task,
% move reallycomplexscript.lua scripts % move helloworld.lua scripts
Which already seems like a lot of work–to say nothing of a more complex case having several dozen files.
This is where wildcards comes to the rescue. Rather than specifying each file individually, we can refer to them all in one go. In effect, we can issue a command that says “move everything with a .lua extension into the lua folder”. The command is,
% move *.lua scripts
* in the command is called a wildcard. What this command says is to
take all of the files that end in .lua, no matter what the rest of the filename
is, and do something with them. As shown here, it has the desired effect,
Generally speaking, wildcards are only used to specify input files to a command. You cannot use wildcards to specify the output of a move or copy command, for example. This should make sense: wildcards need to match with existing filenames. Specifying outputs (which are often new files) would require a more advanced pattern matching system to “fill in the blanks” of the filename.
There are exceptions to this, however. Most notably, the
is a special case that uses wildcards for both source and destination
arguments. This allows for bulk renaming of files based on some pattern,
a task which cannot be conveniently done with
For example, what if we suddenly realized that we had made a mistake, and that
our supposed Lua scripts were actually written in Perl, and thus ought to have
a .pl extension, rather than a .lua extension? After firing the intern who no
doubt made the error, how can we fix it? We could use
move to rename each
file individually, but this would be fairly manual. Instead, we can do it all
at once using a single call to
% cd scripts % rename *.lua *.pl
As you can see, the rename command will use standard wildcarding to select its
input files. For each output file, the part that matched the wildcards will be
left in place, and the parts specified explicitly will be swapped. In this
case, the filename itself is wildcarded on both sides, so remains unchanged.
.lua on the input side will be replaced with
.pl on the output.
I won’t belabour the point here. Experiment with
rename and you’ll get a feel
Specifying All Files in a Directory
You can also use a wildcard to specify all files within a given directory. For example, if we decided that we wanted to pull those newly renamed Perl scripts back into our programming directory, we can do the following (with our working directory set back to the programming directory)
% move scripts\* .
Multiple Wildcards in a Single Argument
You can also include multiple wildcards in a single argument. For example, a common use case of this is manipulating files with a date or timestamp in their name, such as the following directory of jpeg image files,
We can move all of the photographs taken in November of 2020 into the appropriate directory with a single move command,
% move *_11-*-20* November-2020
It is worth taking some care with wildcards. It’s very easy to make a mistake
with them. For example, the following
move command may appear very similar to
the one above,
% move *_*11-*20* November-2020
But, it contains a bug. Can you see what that bug might be?
The second wildcard will match all of the photographs taken in November 2020,
however it will also match photographs taken on the 20th of November, regardless
of the year, such as
move the dangers of this aren’t particularly great–just a little
inconvenient most of the time–but you can imagine the havoc that could be
wreaked by an incorrect wildcard in a
There is a second type of wildcard that you can use that is a bit more
*, for when you only want to match on a single character:
The important distinction is simply this: the
* wildcard will expand to
encompass as many characters as it can. So if your wildcard is
will match any file which begins with a
t and has a
regardless of how many (if any) characters fall between. All of the
following files will match with this wildcard,
t.txt ta.txt tasdf.txt testfile.txt
? allows only a single character, in the same spot as the
vary (and also requires that a character exists in that spot). So of the above
ta.txt would be a match for
You can, of course, add multiple
? wildcards (just like the
*s), and mix
* in the same command. This can be handy if you’re doing matching on
files with a very strict naming scheme and can rely on exact character counts.
For example, if we wanted to select all photos above from a specific month and
year, but with any prefix and any 2-digit day, we could do that with,
% move *_11-??-20.jpg November-2020
effectively forcing the shell to only let the day and prefix portions of the filename vary, while also requiring that the day portion be exactly two digits.
In this article, we discussed using wildcards to allow commands to process
multiple files at once. Wildcards are special characters that are used to
facilitate pattern matching of filenames. The
* character will match with
any sequence of zero-or-more characters, and the
? character will match
with any single character. On Command Prompt, wildcard processing is handled by
individual programs, but they are supported by the majority of standard
In the next article, we will discuss the concept of options, special arguments that can be provided to various commands to configure their behavior.