What are wildcards and globbing?
Tags: linux
Published: 2022-03-21 12:07:24

---
title: "What are wildcards and globbing?"
published: true
description: "A gentle introduction to wildcards and globbing in Linux."
tags: ["linux"]
canonical_url: https://ashutoshbw.github.io/blog/wildcards-and-globbing/
---
The two features of Linux shells &mdash; wildcards and globbing &mdash; can sometimes save us a lot of time by letting us communicate to the computer to match filenames in an efficient way to do something with them like displaying, copying, moving, removing etc.

A **wildcard** is a character or a set of characters that acts as a placeholder for other characters. A **wildcard character**(aka **metacharacter**) is a wildcard containing a single character. Wildcards looks like this: `*`, `?`, `[a-z0-4]`. We will learn the meaning of these symbols in a minute.

**Wildcard pattern**(aka **glob pattern**, **glob** or just **pattern**) is a string that contains wildcard in it. Shell can use them to match filenames. They looks somewhat like this: `*ing.pdf`, `photo-??.jpg`, `photo-[0-9][0-9].jpg` etc.

**Globbing** is the operation of macthing items from a list of strings using wildcard pattern and returning the list of matched items. 

Globbing is frequently used for matching filenames in Linux. In this context it is also sometimes referred to as **filename expansion**, **filename substitution**, **filename generation**(in zsh specially) or **pathname expansion**.

### Where these strange names came from
To satisfy your infinite curiousity, here goes their etymology:

* In card games wildcard is used describe a card which can have any value as it's holder desires. This is where the term came from. 
* Originally `glob` was the program to do what today we mean by globbing in a smaller scale. The name `glob` came from global.

Cool! Let's see some commonly used wildcards in the next section.

## Common wildcards
Below are the explanation of some wildcards[^1] which are present in all good shells out there like bash and zsh:
* `*`: Matches zero or more character.
* `?`: Matches any one character. 
* `[string]`: Matches exactly one character that is a member of the string string. This is called a character class. As a shorthand, string may contain ranges, which consist of two characters with a dash between them. For example, the class `[a-z0-9_]` matches a lowercase letter, a number, or an underscore. You can negate a class by placing a `!` or `^` immediately after the opening bracket. Thus, `[^A-Z@]` matches any character except an uppercase letter or an at sign. 
* `\`: Removes the special meaning of the character that follows it. This works even in character classes.


**Note**: Most shells have their own way of extending the above wildcards. These are known as **extended globbing** and are usually not enabled by default. We will not discuss about them in this article.


### Examples
Below are some glob patterns and their explanation:
* `*.jpg` will match strings ending with `.jpg`. 
* `???.png` will match strings starting with any 3 characters and then ending with `.png`.
* `[cb]at.gif` will match either `cat.gif` or `bat.gif`.
* `[a-z]*[0-9]` will match all strings that starts with a lowercase letter and ends with a digit with any number of any characters in between.

Such patterns can be used with any shell commands like `ls`, `cp`, `mv` etc. There is a important point to tell you right now: The command can't see these patterns. Shell expands these patterns and gives the outputs to the command in the place of respective patterns.

For example the following command will show all files in `/usr/bin` that has `ff` somewhere in the filename:
```zsh
ls /usr/bin/*ff*
```

On my system, the output is:
```
/usr/bin/btfdiff    /usr/bin/fftwf-wisdom         /usr/bin/lzdiff          /usr/bin/ppm2tiff    /usr/bin/swapoff     /usr/bin/tiffinfo
/usr/bin/bzdiff     /usr/bin/fftwl-wisdom         /usr/bin/mmroff          /usr/bin/raw2tiff    /usr/bin/tiff2bw     /usr/bin/tiffmedian
/usr/bin/clockdiff  /usr/bin/fftwq-wisdom         /usr/bin/nroff           /usr/bin/roff2dvi    /usr/bin/tiff2pdf    /usr/bin/tiffset
/usr/bin/codiff     /usr/bin/fftw-wisdom          /usr/bin/obs-ffmpeg-mux  /usr/bin/roff2html   /usr/bin/tiff2ps     /usr/bin/tiffsplit
/usr/bin/diff       /usr/bin/fftw-wisdom-to-conf  /usr/bin/pamtohdiff      /usr/bin/roff2pdf    /usr/bin/tiff2rgba   /usr/bin/tifftopnm
/usr/bin/diff3      /usr/bin/gdiffmk              /usr/bin/pamtotiff       /usr/bin/roff2ps     /usr/bin/tiffcmp     /usr/bin/troff
/usr/bin/diffimg    /usr/bin/giffix               /usr/bin/pdffonts        /usr/bin/roff2text   /usr/bin/tiffcp      /usr/bin/xtotroff
/usr/bin/fax2tiff   /usr/bin/groff                /usr/bin/pdfroff         /usr/bin/roff2x      /usr/bin/tiffcrop    /usr/bin/xzdiff
/usr/bin/ffmpeg     /usr/bin/groffer              /usr/bin/pnmtotiff       /usr/bin/sdiff       /usr/bin/tiffdither  /usr/bin/zdiff
/usr/bin/ffplay     /usr/bin/hdifftopam           /usr/bin/pnmtotiffcmyk   /usr/bin/sqldiff     /usr/bin/tiffdump
/usr/bin/ffprobe    /usr/bin/hwloc-diff           /usr/bin/poweroff        /usr/bin/srt-ffplay  /usr/bin/tiffgt
```

If you want the pattern literally, you have two options:
* Surround the pattern with single quotes(`'`) or double quotes(`"`):
    ```zsh
    touch 'crazy*24'
    ```
    **Note**: `touch` updates the timestamps of existing file. If the argument contains non-existent filename then an empty file is created by that name.
* Use the `\` wildcard to escape other wildcards:
    ```zsh
    touch crazy\*42
    ```

## Further study
* For a more in depth study of the wildcards and globbing(including extended ones) in bash and zsh see:
  * Enter `man 7 glob` in your terminal.
  * [GNU bash manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html)
  * [zsh doc](https://zsh.sourceforge.io/Doc/Release/Expansion.html#Filename-Generation)

[^1]: [GNU Findutils](https://www.gnu.org/software/findutils/manual/html_node/find_html/Shell-Pattern-Matching.html)

---

If this article helped you, please buy me a coffee:
<a href="https://www.buymeacoffee.com/ashutoshbiswas" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>