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.