59

I understand what brace expansion is, but I don't know how best to use it.

When do you use it?
Please teach me some convenient and remarkable examples if you have your own tip.

1
  • For the record, {a,b} brace expansion was first introduced in csh in the late 70s and the {1..10} {001..100} {a-z} variant by zsh in the early 90s, and yet more variations in ksh93 in the mid 2000s. Beside the shells you've already tagged, it's also available in fish and yash. Jun 22, 2022 at 19:10

7 Answers 7

60

Brace expansion is very useful if you have long path names. I use it as a quick way to backup a file:

cp /a/really/long/path/to/some/file.txt{,.bak}

will copy /a/really/long/path/to/some/file.txt to /a/really/long/path/to/some/file.txt.bak

You can also use it in a sequence. I once did so to download lots of pages from the web:

wget http://domain.example/book/page{1..5}.html

or

for i in {1..100}
do
   #do something 100 times
done
4
  • 9
    This can be used for argument duplication as well. Say you have some program which requires a '-f' argument for every file to operate on. instead of doing program -f file1 -f file2 -f file3, you can do program "-f file"{1..3}
    – phemmer
    Feb 1, 2011 at 20:42
  • This is a shame. I just discovered it but do the backup thing on extra-long paths for years without knowing rhis. Thanks.
    – smonff
    May 20, 2014 at 12:41
  • 2
    @Patrick: That fails because program gets three words: "-f file1" "-f file2" "-f file3", instead of 6: "-f" "file1" "-f" "file2" "-f" "file3".
    – musiphil
    May 18, 2015 at 18:52
  • 1
    @dogbane: Using expansion for use in a for loop is a bit pointless, since you can write for ((i=1; i<=100; i++)) and it is more efficient.
    – musiphil
    May 18, 2015 at 18:54
37
+50

Brace expansion comes very handy when creating large directory structures:

mkdir -p dir1/{subdir1,subdir2}/{subsubdir1,subsubdir2}

This will give you

find dir1 -type d
dir1
dir1/subdir1
dir1/subdir1/subsubdir1
dir1/subdir1/subsubdir2
dir1/subdir2
dir1/subdir2/subsubdir1
dir1/subdir2/subsubdir2

You could even go one step further and put brace expansion into brace expansion:

mkdir -p dir1/{subdir{1,2}}/{subsubdir{1,2}}

This will give you the same directory structure as the example above.

3
  • 3
    Nesting is nice, but your nesting example (mkdir -p dir1/{subdir{1,2}}/{subsubdir{1,2}}) doesn't actually serve any purpose. You could have just done this: mkdir -p dir1/subdir{1,2}/subsubdir{1,2}.
    – iconoclast
    Jul 14, 2011 at 18:40
  • @iconoclast, it does serve a purpose if you interpret subdir1 and subdir2 in the non-literal sense. Replace subdir1 with cat and subdir2 with dog for example.
    – ephsmith
    Jul 26, 2012 at 10:55
  • 2
    @ephsmith: if you interpret "subdir1" as standing in for "cat" and "subdir2" for "dog", then the nesting example fails, since it uses subdir{1,2}, and there is no string that you can replace "subdir" with that will make subdir{1,2} return {cat,dog}.
    – iconoclast
    Jul 26, 2012 at 21:04
23

I use it when I want to reduce typing:

geany /path/to/file1 /path/to/file2
# versus
geany /path/to/file{1,2}

Another example:

wajig install libpam0g-dev libiw-dev libdb-dev
# versus
wajig install lib{pam0g,iw,db}-dev
0
13

I use it to compare actual test output to desired test output during development. If test #41 fails, it's easy to see what the difference between the test output (in file tests.output/041) and the desired output (in file tests.out/041):

$ diff tests.{out,output}/041
12

Some frequent cases for me are:

For renaming:

mv myText.{txt,tex}

or

mv myText.tex{,.old}

or

cp myText.tex{,.backup}

(Although it's less messy to use version control for the last 2 tasks.)

For comparing (already mentioned):

diff path{1,2}/a.txt
4

There are several great answers here, but none of them mention when not to use brace expansion. Like the other answerers, I use brace expansion on the command line quite a bit. I also use it in my aliases and functions since I can expect a smart shell.

I do not use it in my shell scripts (unless there's some other reason the scripts should be bash or zsh, though in those cases, it's best to upgrade to a "real" scripting language like perl or python). Brace expansion is not portable since it is not in the POSIX shell standard. Even if it works in your /bin/sh-shebanged shell scripts, it will not work on systems with more stripped /bin/sh shells (e.g. dash).

In the case of a difference of a single digit, you don't need brace expansion; a character class will suffice:

Bashism:

diff file{1,2}

Portable:

diff file[12]
2
  • 6
    A difference is that file{1,2} will always expand to file1 file2, while file[12] expands only to existing filenames: i.e. if file1 exists but file2 doesn't, file[12] expands to file1 only. The [] expansion is really a restricted version of ? expansion (and they are called "pathname expansions").
    – musiphil
    May 18, 2015 at 18:57
  • Correct, brace expansion is not shell globbing (a.k.a. pathname expansion). That's a good call-out that hasn't really been mentioned yet: brace expansion is better at noting unexpectedly absent paths. You can also glob inside brace expansion.
    – Adam Katz
    May 18, 2015 at 21:28
2

After splitting a very big file with

split -b 100m hugeFile.zip part.

let's suppose it splitted into 262 pieces, in other words part.aa,part.ab,part.ac ... part.kb

Your can join those pieces again by nesting brace expansions, like this

cat part.{{a..j}{a..z},k{a..b}} > hugeFile.zip

You must log in to answer this question.

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