4

The command echo {1..3}-{1,2} prints 1-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 ?

2
  • 2
    They are called brace expansion, obviously. It's one of several expansions done by bash. You can read on it in manual.
    – PesaThe
    Dec 6, 2017 at 1:02
  • Thanks! Posted as answer, this could get a check mark :)
    – Matmarbon
    Dec 6, 2017 at 1:12

2 Answers 2

6

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)

1
  • @Kusalananda Thanks for the edit. For some reason I thought the question was bash specific.
    – PesaThe
    Dec 6, 2017 at 10:07
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .