Bash Wildcards

Posted: 8th November 2010 by Tim in Bash
Tags: , , , , , ,

There are lots crazy things you can do with bash. Some of the more useful of these are the bash wildcards. This post will explore the *, ?, {...}, [...] and [!...] wildcards.

For the examples below, we will demonstrate wildcard usage with the ls command, and assume that the current directory has the following files:

component.cpp
component.h
legacy.c
legacy.h
readme.txt
soap_test1.xml
soap_test2.xml
soap.xsd
system.mk

*

The * wildcard is used to represent zero or more characters. Used on it’s own the wildcard will select everything, or used with other characters it can represent part of a name we don’t care about. For example, to list all files which end in .h, we could type

ls *.h

The * here states that we don’t care what comes before the dot. This will match the following files:

component.h legacy.h

?

The ? wildcard is used to represent any single character. This character could be a letter, a number, or any other character you can think of. This may not seem all that useful, but if you wanted to grab all the xml and xsd files from the list above, you could run:

ls *.x??

Here, the star states that we don’t care what comes before the dot, and the dot must be followed by an x and any two other characters. So for this example, we would get:

soap_test1.xml soap_test2.xml soap.xsd

{...}

Strings enclosed in curly braces {...}, separated by commas are used to match any of those strings in a filename. For example, if we want to list all files ending in .h or .cpp, we could run the following:

ls *.{cpp,h}

Again, we don’t care what’s before the dot, and the dot can only be followed by cpp or h. So this will return:

component.cpp component.h legacy.h

[...]

Characters enclosed in square brackets [...] are used to match any of those characters. For example, to list all of the .c and .h files, we could run:

ls *.[ch]

Note that files with characters after the c or h will not match (ie: .cpp files will not match). So this will return:

component.h legacy.c legacy.h

[!...]

If the square brackets have a ! as the first character, it means we want to match any character which is not in that list. For example, to list all files whose extensions do not start with x or c, we could run the following:

ls *.[!xc]*

See here how we have added a * to the end – this means that we want to check all files, not just those with single-character extensions (ie: .cpp files will not be listed). So this will return:

component.h legacy.h readme.txt system.mk

Other examples

Obviously we can mix and match these wildcards, as shown below:

ls ?*.[!ct]{ml,sd}
soap_test1.xml soap_test2.xml soap.xsd

ls *[ae]*.[!x]??
component.cpp readme.txt