Using {} to Construct Command Line Arguments
When working on the command line, we often encounter scenarios where we need to perform operations on multiple argument entries, with file names being one of the most common cases. To handle this situation, both Bash and Zsh provide comma-separated curly brace lists, such as:
echo {one,two,three}
Before passing the arguments to the echo command, the shell first expands the curly braces list and generates the following three argument entries:
one two three
By leveraging {} (curly brackets), we can achieve numerous interesting functions, some of which I frequently use are listed below. I encourage you to generalize and apply them flexibly when learning.
Backup Files
I’ve found that many friends back up files using the following command:
cp file file.bak
This command backups file as file.bak. With {}, we can rewrite it as:
cp file{,.bak}
The {,} expansion of the cp command argument file{,.bak} becomes file file.bak. The comma (,) is essential here; otherwise, the shell won’t expand it.
Similarly, we can use tar in conjunction with {} to create archives:
tar cf docs{.tar,}
Here, the tar command archives the docs directory as docs.tar.
Generating Sequences
For items arranged in a certain order, instead of using a comma (,) , shell also supports specifying a range using .. (two dots).
echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
The echo command will print out all lowercase letters from a to z.
For example:
echo {0..9}
0 1 2 3 4 5 6 7 8 9
The echo command will display the numbers from 0 to 9.
You can also add leading zeros before the numbers at the beginning of the interval, for example:
echo {01..10}
This will list the following numerical sequence:
01 02 03 04 05 06 07 08 09 10
Furthermore, we can also add a step value at the end of the range:
echo {1..9..2}
The last digit 2 is the step value, so only odd numbers are listed:
1 3 5 7 9
In Zsh, the step value can be negative, in which case the numbers are listed in reverse order, for example:
echo {1..9..-2}
9 7 5 3 1
In Bash, the same effect can be achieved by swapping the start and end of the range, such as:
echo {9..1..2}
9 7 5 3 1
Finally, let’s look at a practical example of using sequences. By combining generated sequences with paths, it’s particularly useful when downloading multiple files.
wget https://linuxtoy.org/img/{1..5}.png
The wget command will download the image files 1.png, 2.png, 3.png, etc. from https://linuxtoy.org in sequence.
Notably, aside from the .. (dot notation) for range representation, Zsh also supports - (dash) for range representation, but requires the braceccl option to be enabled.
setopt braceccl
echo {A-Za-z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
After enabling the braceccl option with setopt, executing echo {A-Za-z} lists all uppercase and lowercase letters.
Combination and Nesting
Shell’s {} structure is very flexible and powerful, especially when used in combination and nested. Let’s first look at an example of {} in combination.
mkdir -p 2019/{01..12}/{baby,photo}
In this example, we use two consecutive {}, creating baby and photo sub directories within each month’s directory. This command is essentially executing the following:
mkdir -p 2019/01/baby 2019/01/photo \
2019/02/baby 2019/02/photo \
2019/03/baby 2019/03/photo \
2019/04/baby 2019/04/photo \
2019/05/baby 2019/05/photo \
2019/06/baby 2019/06/photo \
2019/07/baby 2019/07/photo \
2019/08/baby 2019/08/photo \
2019/09/baby 2019/09/photo \
2019/10/baby 2019/10/photo \
2019/11/baby 2019/11/photo \
2019/12/baby 2019/12/photo
It’s boring to type the latter manually, but with the help of {}, we can make it easier
The {} structure can be used in combination and nested. For example:
echo {{A..Z},{a..z},{0..9}}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
The outer {} of the echo command include 3 inner {}, listing all uppercase letters, lowercase letters, and numbers from 0 to 9.
For more useful command-line tips, refer to Mastering the Command Line Like a Hacker.