49

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.

52

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.com/book/page{1..5}.html

or

for i in {1..100}
do
   #do something 100 times
done
  • 8
    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} – Patrick Feb 1 '11 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 '14 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 '15 at 18:52
  • @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 '15 at 18:54
31
+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
    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 '11 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 '12 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 '12 at 21:04
21

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
12

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
10

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
3

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]
  • 3
    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 '15 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 '15 at 21:28

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.