brace expansion in linux simplfied with examples

If have been bash programming, then you must have seen brace expansion syntax being used in shell commands. The main purpose of brace expansion is automatically generate a set of strings (or numbers) that follows a general pattern.

The pattern is enclosed with curly braces: '{' and '}'. This leads it to be commonly referred to as the brace expansion syntax. The curly braces have special meaning with in the shell and whatever it encloses is interpreted differently to generate a set of values.

The generic syntax of brace syntax is usually a starting value and an ending value separated by two periods, also known as sequence specification. Different values can also be separated by commas, which gives it even more versatility.

It is probably best explained with examples. The simplest of the brace expansion is

{1..20} => generates numbers from 1 to 20.

You can do negative integers and you can do it in decreasing order as well.

{3..-3} => generates numbers -3 -2 -1 0 1 2 3

If you are using Bash 4.0 or later, then you can also specify an increment value. The increment value is specified as the third values again separated by two periods. The example below will generate numbers starting with 4 in increments of 2 up till 10.

{4..10..2} => generates the numbers 4 6 8 10

Now the same goes for characters as well. You can generate a set of characters. As with numbers you can do either direction as well.

{k..s} => generates k l m n o p q r s

Now, you can combine both meaning you can use both numbers and characters together.

img{0..4}.jpg => generates img0.jpg img1.jpg img2.jpg img3.jpg img4.jpg

As you can see it can useful in generating file names. Also, the braces can be nested.

img{{1..3},{6..8}}.jpg => generates img1.jpg img2.jpg img3.jpg img6.jpg img7.jpg img8.jpg
img{a,b,c{0..3},d} => generates imga imgb imgc0 imgc1 imgc2 imgc3 imgd

The brace expansion can be useful when you don't want to type out long folder and file names when used as arguments to commands.

rm -f /folder/f{1..3}/{one,two} => will delete /folder/f1/one /folder/f2/one ..../folder/f3/two, /folder/f3/two etc