ブレース展開
bashの機能にブレース展開(Brace Expansion)があります。ブレースは数学の分野では'{}'のことで、ブレース展開は直訳すると中括弧展開とか波括弧展開とそのままの意味になります。
ブレース展開は以下のようなものになります。
1 2 |
$ echo a{b,c,d}e abe ace ade |
このブレース展開は{x..y[..inc]}のように範囲を指定して用いることもできます。
1 2 |
$ echo a{a..i}e aae abe ace ade aee afe age ahe aie |
連番の文字列を生成するために用いると
1 2 |
$ echo {1..20} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
のようにして連番の文字列を生成できます。
連番の増加量を操作することもでき、数値を減少させることもできます。
1 2 3 4 5 6 7 8 9 10 |
$ echo {1..10..2} 1 3 5 7 9 $ echo {2..10..2} 2 4 6 8 10 $ echo {-10..10} -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 $ echo {10..-10..-2} 10 8 6 4 2 0 -2 -4 -6 -8 -10 $ echo {10..-10} 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 |
ブレース展開の文字列の前後に文字列を追加するとファイル名のようにすることができます。
1 2 |
$ echo abc-{1..20}.txt abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt abc-6.txt abc-7.txt abc-8.txt abc-9.txt abc-10.txt abc-11.txt abc-12.txt abc-13.txt abc-14.txt abc-15.txt abc-16.txt abc-17.txt abc-18.txt abc-19.txt abc-20.txt |
連番を改行したい場合はfor文やxargsコマンドを用いると便利だと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ for i in {1..5}; do echo abc-$i.txt; done abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt $ $ echo abc-{1..5}.txt | xargs -n1 abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt |
ゼロパディングを行いたい場合は、数値の頭に0をつけます。
1 2 3 4 5 6 7 8 9 10 11 |
$ echo {00..0100..50} '---' {00..1000..200} | xargs -n1 0000 0050 0100 --- 0000 0200 0400 0600 0800 1000 |
seqコマンドとawkコマンド
連番の文字列を生成するのによく利用するコマンドはseqコマンドでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ seq 1 5 1 2 3 4 5 $ $ seq 1 2 10 1 3 5 7 9 |
連番の後にprintf関数が利用できると連番を都合がよい形式に加工ができます。
ここでは、awkコマンドからprintf関数を利用します。
1 2 3 4 5 6 |
$ seq 1 5 | awk '{printf "%02d\n",$1}' 01 02 03 04 05 |
また、print関数とsprintf関数を利用しても良いでしょう。
1 2 3 4 5 6 |
$ seq 1 5 | awk '{print "abc-"sprintf("%d",$1)".txt"}' abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt |
seqコマンドとxargs+printfコマンド
awkコマンド等からprintf関数を利用しなくても、基本的にprintfコマンドがあるでしょう。
しかし、単純にseqコマンドからprintfコマンドへパイプをつないでも利用できないので、xargsコマンドを利用します。
1 2 3 4 5 6 |
$ seq 1 5 | xargs -n1 printf '%02d\n' 01 02 03 04 05 |
xargsコマンドの取得する引数の数を調整すれば、文字列を少し特殊に加工できます。
1 2 3 4 |
$ seq 1 5 | xargs -n2 printf '%02d %03d\n' 01 002 03 004 05 000 |
連番の文字列を並べる
pasteコマンドを利用すると連番の文字列を並べることができます。
1 2 3 4 5 6 |
$ paste <(seq 1 5) <(seq 5 -1 1) 1 5 2 4 3 3 4 2 5 1 |
<(command)はプロセス置換でコマンドの出力がファイルの代わりになります。
以下の感じにするとテストデータっぽく見えるかもしれません。
1 2 3 4 5 6 |
$ paste <(seq 1 5) <(seq 5 -1 1) <(seq 20 20 100)| xargs -n3 printf '%003d %d %.2f\n' 001 5 20.00 002 4 40.00 003 3 60.00 004 2 80.00 005 1 100.00 |
ファイル作成のコマンドを一気に実行
連番のテストファイルを一気に作成したい場合はxargsコマンドが利用できます。
1 2 3 |
$ echo abc-{1..5}.txt | xargs -n1 touch $ ls abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt |
また、シェルの標準入力からコマンドを読み取るオプション(例えば、bashではsオプション)を用いても良いでしょう。
まずは、生成したいテストファイルと作成するコマンドを確認してから
1 2 3 4 5 6 7 8 9 10 11 12 |
$ seq 1 5 | awk '{printf "abc-%d.txt\n",$1}' abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt $ seq 1 5 | awk '{printf "touch abc-%d.txt\n",$1}' touch abc-1.txt touch abc-2.txt touch abc-3.txt touch abc-4.txt touch abc-5.txt |
'bash -s'にパイプで渡すとファイルを作成できます。
1 2 3 |
$ seq 1 5 | awk '{printf "touch abc-%d.txt\n",$1}' | bash -s $ ls abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt |
もちろん、コマンド作成段階で中間ファイルを一度作ってからパイプで渡しても良いでしょう。
1 2 3 4 5 6 7 8 9 10 |
$ seq 1 5 | awk '{printf "touch abc-%d.txt\n",$1}' > tmpfile $ cat tmpfile touch abc-1.txt touch abc-2.txt touch abc-3.txt touch abc-4.txt touch abc-5.txt $ cat tmpfile | bash -s $ ls abc-1.txt abc-2.txt abc-3.txt abc-4.txt abc-5.txt tmpfile |
うまい具合に文字列を加工すれば、ファイルの作成だけではなく、ファイルのリネームや特定のファイル削除にも利用できます。