BASH: Single character/range pattern matching

When searching for files and only a single character or range is different, use the [square bracket] to locate the target.

Sample list of different filenames

$ ls -l file*
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file1
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file10
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file2
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file3
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file4
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file5
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file6
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file7
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file8
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file9
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:56 fileA
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:55 file_for_james
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:56 fileb
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:55 files_for_ken

Single character substitution

With single character substitutions, the shell will attempt to locate files with each character in the brackets. Ex: file[abc] will locate filea, fileb, and filec.

Only fileA matched the given pattern

$ ls -l file[aAB]
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:56 fileA

A lot of different possibilities were provided but only 2 existed

$ ls -l file[aABbc]
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:56 fileA
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:56 fileb

Range Pattern Matching

In range pattern matching, it can instead search a given range of characters instead. Ex: file[a-c] will locate filea, fileb, and filec. This is the same as file[abc] but the hyphen gives it a range which the shell will automatically expand for you. Range can also do numbers like  file[1-3] .

Search for a range of numbers

$ ls -l file[1-5]*
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file1
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file10
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file2
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file3
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file4
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file5

Search for 2 number ranges

Note: Both do the same thing

$ ls -l file[1-5,7-9]*
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file1
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file10
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file2
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file3
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file4
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file5
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file7
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file8
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file9

$ ls -l file[1-57-9]*
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file1
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file10
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file2
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file3
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file4
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file5
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file7
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file8
-rw-r--r-- 1 jvalero wheel 0 Jun  5 06:53 file9

Why did it also find  file10 ? It was looking for anything matching file1*  and file10 fits the bill. It doesn’t consider anything after the first range substitution character.

Summary

These are great tricks to narrow down searches, locate/use similarly named files, make queries more concise, and just look like a pro in shell expansion. Also check out my article about substituting whole words.

Leave a Reply

Your email address will not be published. Required fields are marked *