0

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
    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 '17 at 1:02
  • Thanks! Posted as answer, this could get a check mark :) – Matmarbon Dec 6 '17 at 1:12
4

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)

  • @Kusalananda Thanks for the edit. For some reason I thought the question was bash specific. – PesaThe Dec 6 '17 at 10:07
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.