How does curly brace expansion work in the shell?
Solution 1
They are called brace expansion.
It is one of several expansions done by bash
, zsh
and ksh
, filename expansion *.txt
being another one of them. Brace expansion is not covered by the POSIX standard and is thus not portable.
You can read on this in bash manual.
On @Arrow's suggestion: in order to get cat test.pdf test.pdf test.pdf
with brace expansion alone, you would have to use this "hack":
#cat test.pdf test.pdf
cat test.pdf{,}
#cat test.pdf test.pdf test.pdf
cat test.pdf{,,}
#cat test.pdf test.pdf test.pdf test.pdf
cat test.pdf{,,,}
Some common uses:
for index in {1..10}; do
echo "$index"
done
touch test_file_{a..e}.txt
Or another "hack" to print a string 10 times:
printf -- "mystring\n%0.s" {1..10}
Be aware that brace expansion in bash
is done before parameter expansion, therefore a common mistake is:
num=10
for index in {1..$num}; do
echo "$index"
done
(the ksh93
shell copes with this though)
Solution 2
PesaThe's answer answer covers important aspects of the question. There are several things I want to add.
The asterisk in ls *.txt
is handled by the shell and is therefore controlled by shell options which can be changed by shell built-ins. In this case, one can disable asterisk expansion by running set -f
and enable it again by set +f
.
Another thing is that anyone who wants to make the script portable should check the POSIX standard. For example {1..9..2}
expands to 1 3 5 7 9
in bash
4 but does not expand in lower bash
versions or in sh
.
Related videos on Youtube
Matmarbon
Updated on September 18, 2022Comments
-
Matmarbon almost 2 years
The command
echo {1..3}-{1,2}
prints1-1 1-2 2-1 2-2 3-1 3-2
. I understand the way those curly braces can be used. But what actually are they?Is it the job of
sh
/bash
to parse/expand them and deliver the expanded version to the executed program?If so, what other tricks can it do and is there a specification?
Also, is there a name for it?
Is
ls *.txt
handled in a similar way internally?Is there a way to achieve an n-times repetition of an argument? Like (not working, of course, only a concept):
cat test.pdf{*3}
⇒cat test.pdf test.pdf test.pdf
?-
Matmarbon over 6 yearsThanks! Posted as answer, this could get a check mark :)
-
-
PesaThe over 6 years@Kusalananda Thanks for the edit. For some reason I thought the question was
bash
specific.