bashのブレース展開を使用する際、その出力結果を改行して使いたい場合がある。 そんなときは、よくsedやtrでスペースを改行に置換してやったりするのだが、そういった置換処理をせずに改行で出力できないのかなと思ったので、ちょっと調べてみた。

とりあえず、以下の3通りの方法があるようだ。

printfを利用する

多分、一番扱いやすいのではなかろうか。 以下のように、printfの入力元の値を用いることで出力時に改行させることが可能だ。

printf "%s\n" test{01..10}
blacknon@BS-PUB-UBUNTU-01:~$ printf "%s\n" test{01..10}
test01
test02
test03
test04
test05
test06
test07
test08
test09
test10

evalを利用する

知らなかったのだが、evalで以下のようにブレース展開を行うことで、改行した状態にしてechoしてくれるらしい。 スペースをエスケープさせる必要があるのはちょっと面倒だけど、コレは面白い(処理速度はちょっと遅い気がするけど…)。

eval echo\ test{01..10}\;
blacknon@BS-PUB-UBUNTU-01:~$ eval echo\ test{01..10}\;
test01
test02
test03
test04
test05
test06
test07
test08
test09
test10
blacknon@BS-PUB-UBUNTU-01:~$ 
blacknon@BS-PUB-UBUNTU-01:~$ # こういうことらしい
blacknon@BS-PUB-UBUNTU-01:~$ eval echo echo\ test{01..10}\;
echo test01
test02
test03
test04
test05
test06
test07
test08
test09
test10

forを利用する

正直、1行でちゃちゃっとやるには使いにくいのだけど、forで回すと言った方法もある。

for i in test{1..10}; do echo $i; done
blacknon@BS-PUB-UBUNTU-01:~$ for i in test{1..10}; do echo $i; done
test1
test2
test3
test4
test5
test6
test7
test8
test9
test10

気にするほどでもないと思うが、それぞれの速度はこんな感じ。

blacknon@BS-PUB-UBUNTU-01:~$ time (printf "%s\n" test{00001..30000}>/dev/null)

real    0m0.060s
user    0m0.060s
sys     0m0.000s
blacknon@BS-PUB-UBUNTU-01:~$ time (eval echo\ test{00001..30000}\;>/dev/null)

real    0m0.332s
user    0m0.304s
sys     0m0.028s
blacknon@BS-PUB-UBUNTU-01:~$ time (for i in test{00001..30000}; do echo $i; done>/dev/null)

real    0m0.208s
user    0m0.192s
sys     0m0.016s
blacknon@BS-PUB-UBUNTU-01:~$ time (echo test{00001..30000}|tr ' ' '\n'>/dev/null)

real    0m0.058s
user    0m0.052s
sys     0m0.008s
blacknon@BS-PUB-UBUNTU-01:~$ time (echo test{00001..30000}|sed 's/ /\n/g' >/dev/null)

real    0m0.065s
user    0m0.064s
sys     0m0.004s

とりあえず、置換したくなければprintf使っておけば良いのかな。