BraceExpansionでお手軽に複数処理


地味に便利だけどあまり知られていない気がするBraceExpansionを紹介するぜ！

### BraceExpansionって？
`{`,`}`で囲うとその要素の数だけコマンドを複数実行できるのだ

```Zsh
$ echo {k,c}atherine
katherine catherine
```

PS3のキャサリンおもしろいよね

### 例
#### 例えば複数ファイルを作成したりできる
```Zsh
$ echo {Main,Person,Group}.java  # echoで確認
Main.java Person.java Group.java

$ touch {Main,Person,Group}.java

$ ls
Group.java  Main.java   Person.java
```

#### 複数書いたら全組み合わせ展開される
```Zsh
$ mkdir -p {src,test}/main/java/xxx/{api,service,db}

$ tree --charset=C
.
|-- src
|   `-- main
|       `-- java
|           `-- xxx
|               |-- api
|               |-- db
|               `-- service
`-- test
    `-- main
        `-- java
            `-- xxx
                |-- api
                |-- db
                `-- service
```

ディレクトリの切れ目じゃあなくても当然おｋ

```Zsh
$ touch {Person,Group}_{Create,Update,Delete}_Api.java

$ ls
Group_Create_Api.java  Group_Delete_Api.java  Group_Update_Api.java  Person_Create_Api.java Person_Delete_Api.java Person_Update_Api.java
```

#### 連続要素も展開できる
```Zsh
$ touch testdata_{1..5}

$ ls
testdata_1 testdata_2 testdata_3 testdata_4 testdata_5
```

```Bash
$ touch dir_{A..E}

$ ls
dir_A dir_B dir_C dir_D dir_E
```
（何故かアルファベットの方はzshでは展開されなかったので、上記の例はbash）

#### ネストもできる
```Zsh
$ mkdir -p api/{person/{get,post},group/{post,put,delete}}

$ tree --charset=C
.
`-- api
    |-- group
    |   |-- delete
    |   |-- post
    |   `-- put
    `-- person
        |-- get
        `-- post
```

#### mkdirばっかりじゃあなくて消したり
```Zsh
$ touch {1..3}.{java,class,log,bk,test} # サンプル用意

$ ls -l
1.bk
1.class
1.java
1.log
1.test
2.bk
2.class
2.java
2.log
2.test
3.bk
3.class
3.java
3.log
3.test

$ rm *.{log,bk}

$ ls -l
1.class
1.java
1.test
2.class
2.java
2.test
3.class
3.java
3.test
```

#### 探したりもできるよ
```Zsh
$ mkdir {src,test,tool,doc}
$ touch {src,test,tool,doc}/{1..3}.{java,class} # サンプル準備

$ tree --charset=C
.
|-- doc
|   |-- 1.class
|   |-- 1.java
|   |-- 2.class
|   |-- 2.java
|   |-- 3.class
|   `-- 3.java
|-- src
|   |-- 1.class
|   |-- 1.java
|   |-- 2.class
|   |-- 2.java
|   |-- 3.class
|   `-- 3.java
|-- test
|   |-- 1.class
|   |-- 1.java
|   |-- 2.class
|   |-- 2.java
|   |-- 3.class
|   `-- 3.java
`-- tool
    |-- 1.class
    |-- 1.java
    |-- 2.class
    |-- 2.java
    |-- 3.class
    `-- 3.java

$ find {src,test} -name "2.*"
src/2.class
src/2.java
test/2.class
test/2.java
```
特にこの複数箇所を探すのは`for`使ったり`xargs`使ったり、１つずつ実行して上キーでちょい改変したりするよりはずっと楽だよ！

### おまけ (たぶんzsh)
#### 実行前に展開
zshはglob展開が`Tab`で出来るけど、BraceExpansionでも有効

```Zsh
$ touch {1..3}.{java,class,log,bk,test} # サンプル準備

$ rm *.{log,bk}                         # ここでTab

$ rm 1.log 2.log 3.log 1.bk 2.bk 3.bk   # 当然、条件に合う要素のみ
```
rm系とかは実行前に展開して消しすぎないか確認する癖を付けるのが大事！

#### 展開のUndo
```Zsh
$ rm *.{log,bk}                         # ここでTab

$ rm 1.log 2.log 3.log 1.bk 2.bk 3.bk   # ここでctrl-x,u

$ rm *.{log,bk}                         # 戻る
```

#### 展開せずに結果をチラ見
```Zsh
$ echo 201{5,6}-{01..12} # ここでctrl-x,g

$ echo 201{5,6}-{01..12}
2015-01  2015-03  2015-05  2015-07  2015-09  2015-11  2016-01  2016-03  2016-05  2016-07  2016-09  2016-11  
2015-02  2015-04  2015-06  2015-08  2015-10  2015-12  2016-02  2016-04  2016-06  2016-08  2016-10  2016-12  
```
こっちの方は複雑なコマンドを結果を見ながらちょい改変したりに向いている


いじょーー！

### 参考
[Learning the shell](http://linuxcommand.org/lc3_lts0080.php)