SQL
Globbing
DuckDB supports file name expansion, also known as globbing, for discovering files.
DuckDB's glob syntax uses the question mark (` ?`) wildcard to match any single character and the asterisk (` *`) to match zero or more characters.
In addition, you can use the bracket syntax (` [...]`) to match any single character contained within the brackets, or within the character range specified by the brackets. An exclamation mark (` !`) may be used inside the first bracket to search for a character that is not contained within the brackets.
To learn more, visit the [“glob (programming)” Wikipedia page](https://en.wikipedia.org/wiki/Glob_(programming)).  
#### `GLOB` {#docs:sql:functions:pattern_matching::glob}  
<div id="rrdiagram3"></div>  
The `GLOB` operator returns `true` or `false` if the string matches the `GLOB` pattern. The `GLOB` operator is most commonly used when searching for filenames that follow a specific pattern (for example a specific file extension).  
Some examples:  
```sql
SELECT 'best.txt' GLOB '*.txt';            -- true
SELECT 'best.txt' GLOB '????.txt';         -- true
SELECT 'best.txt' GLOB '?.txt';            -- false
SELECT 'best.txt' GLOB '[abc]est.txt';     -- true
SELECT 'best.txt' GLOB '[a-z]est.txt';     -- true
```  
The bracket syntax is case-sensitive:  
```sql
SELECT 'Best.txt' GLOB '[a-z]est.txt';     -- false
SELECT 'Best.txt' GLOB '[a-zA-Z]est.txt';  -- true
```  
The `!` applies to all characters within the brackets:  
```sql
SELECT 'Best.txt' GLOB '[!a-zA-Z]est.txt'; -- false
```  
To negate a GLOB operator, negate the entire expression:  
```sql
SELECT NOT 'best.txt' GLOB '*.txt';        -- false
```  
Three tildes (` ~~~`) may also be used in place of the `GLOB` keyword.  
<div class="narrow_table"></div>  
| GLOB-style | Symbolic-style |
|:---|:---|
| `GLOB` | `~~~` |  
#### Glob Function to Find Filenames {#docs:sql:functions:pattern_matching::glob-function-to-find-filenames}  
The glob pattern matching syntax can also be used to search for filenames using the `glob` table function.
It accepts one parameter: the path to search (which may include glob patterns).  
Search the current directory for all files:  
```sql
SELECT * FROM glob('*');
```  
<div class="narrow_table monospace_table"></div>  
|     file      |
|---------------|
| duckdb.exe    |
| test.csv      |
| test.json     |
| test.parquet  |
| test2.csv     |
| test2.parquet |
| todos.json    |  
#### Globbing Semantics {#docs:sql:functions:pattern_matching::globbing-semantics}  
DuckDB's globbing implementation follows the semantics of [Python's `glob`](https://docs.python.org/3/library/glob.html) and not the `glob` used in the shell.
A notable difference is the behavior of the `**/` construct: `**/⟨filename⟩` will not return a file with `⟨filename⟩` in top-level directory.
For example, with a `README.md` file present in the directory, the following query finds it:  
```sql
SELECT * FROM glob('README.md');
```  
<div class="narrow_table monospace_table"></div>  
|   file    |
|-----------|
| README.md |  
However, the following query returns an empty result:  
```sql
SELECT * FROM glob('**/README.md');
```  
Meanwhile, the globbing of Bash, Zsh, etc. finds the file using the same syntax:  
```bash
ls **/README.md
```  
```text
README.md
```