LinuxやmacOSの標準シェルとして広く利用されているBashには、コマンド入力を効率化するための強力な機能が数多く備わっています。
その中でも、ブレース展開(Brace Expansion)は、特定のパターンに基づいた文字列を素早く生成できる非常に便利な機能です。
ブレース展開をマスターすることで、煩雑なタイピング作業を大幅に削減し、ミスを防ぎながらスマートにコマンドを実行できるようになります。
本記事では、初心者の方から上級者の方まで役立つ、Bashのブレース展開の基礎から応用テクニックまでを詳しく解説します。
ブレース展開とは何か
ブレース展開とは、波括弧{ }を使用して、その中に記述された複数の文字列や数値のパターンを一度に展開するシェルの機能です。
この機能は変数の展開やワイルドカードの展開よりも前に実行されるという特徴を持っています。
例えば、複数のファイルを作成したり、複雑なディレクトリ構造を一瞬で構築したりする際に威力を発揮します。
ブレース展開を使用することで、同じようなコマンドを何度も繰り返して入力する必要がなくなります。
シェルは実行時にブレース内の要素を解釈し、スペースで区切られた個別の引数としてコマンドに渡します。
基本の文字列展開:カンマ区切りの指定
最も基本的な使い方は、波括弧の中にカンマ区切りで文字列を並べる方法です。
以下の例では、3つの異なる文字列を一度に表示させています。
# カンマ区切りで複数の単語を展開する
echo {apple,banana,cherry}
apple banana cherry
この時、波括弧の中にスペースを入れてはいけないという点に注意してください。
もしスペースを入れてしまうと、Bashはそれを展開の対象として正しく認識できず、単なる文字列として処理してしまいます。
文字列の結合と展開
ブレース展開の真価は、他の文字列と組み合わせた時に発揮されます。
例えば、共通の接頭辞や接尾辞を持つ複数のファイル名を生成することが可能です。
# 接頭辞「file_」とブレース展開を組み合わせる
echo file_{1,2,3}.txt
file_1.txt file_2.txt file_3.txt
このように、固定の文字列の前後にブレースを配置することで、パターンの組み合わせを自動生成できます。
シーケンス展開:数値とアルファベットの連続生成
Bashのブレース展開では、{開始..終了}という記法を用いることで、連続する値を生成できます。
これをシーケンス展開と呼び、大量の連番ファイルやディレクトリを扱う際に非常に重宝します。
数値によるシーケンス
1から10までの数値を生成したい場合は、以下のように記述します。
# 1から10までの数値を生成
echo {1..10}
1 2 3 4 5 6 7 8 9 10
また、逆順で指定することで、カウントダウンのような出力を得ることも可能です。
# 5から1まで逆順に生成
echo {5..1}
5 4 3 2 1
ゼロ埋め(パディング)の指定
ファイル名をソートしやすくするために、01, 02のように桁数を合わせたい場合があります。
その場合は、開始数値の先頭に0を付けるだけで自動的にゼロ埋めが行われます。
# 01から05までのゼロ埋め数値を生成
echo {01..05}
01 02 03 04 05
この機能により、手動で「0」を入力する手間が省け、スクリプトの可読性も向上します。
アルファベットによるシーケンス
数値だけでなく、アルファベットの連続生成もサポートされています。
# aからeまでのアルファベットを生成
echo {a..e}
a b c d e
大文字での指定も可能であり、特定のアルファベット範囲を対象とした一括処理に役立ちます。
増分(ステップ値)の指定
Bashの比較的新しいバージョン(Bash 4.0以降)では、{開始..終了..増分}という形式で、値を飛ばしながら展開することができます。
例えば、偶数だけを生成したい場合は次のように記述します。
# 0から10まで2ずつ増やして生成
echo {0..10..2}
0 2 4 6 8 10
このステップ指定は、特定の周期でデータを処理したい場合に非常に強力なツールとなります。
実践的な利用シーン
ここからは、日常的な業務やサーバ管理で役立つ実践的なブレース展開の使い方を見ていきましょう。
ディレクトリの一括作成
プロジェクトを開始する際、複数の標準的なディレクトリを作成することがよくあります。
mkdirコマンドとブレース展開を組み合わせれば、一行で完了します。
# projectディレクトリ配下にsrc, bin, docs, testsを一度に作成
mkdir -p project/{src,bin,docs,tests}
これにより、一つずつmkdirを実行する手間がなくなり、構造の定義が明確になります。
ファイルのバックアップ作成
設定ファイルを編集する前に、バックアップ(.bak)を作成する場面は多いでしょう。
ブレース展開を使えば、同じファイル名を二度打つ必要はありません。
# config.conf を config.conf.bak としてコピー
cp config.conf{,.bak}
ここで使用している{,.bak}は、空文字と.bakの2つのパターンに展開されます。
つまり、cp config.conf config.conf.bakと入力したのと同じ結果が得られます。
複数ファイルの拡張子一括変更
複数のファイルの拡張子を対象に操作を行う際にも便利です。
例えば、同じ名前で異なる拡張子を持つファイルを一括で削除したい場合などは以下の通りです。
# image.png と image.jpg を削除
rm image.{png,jpg}
ブレース展開のネスト(入れ子)
ブレース展開は入れ子構造にすることができ、より複雑なパターンの組み合わせを生成できます。
# A1, A2, B1, B2 を生成
echo {A,B}{1,2}
A1 A2 B1 B2
また、括弧の中にさらに括弧を入れることも可能です。
# 展開の結果をさらに細分化する
echo {log,error_{old,new}}.txt
log.txt error_old.txt error_new.txt
このテクニックを使えば、多層構造のファイル名生成も簡潔に記述できます。
ブレース展開とワイルドカードの違い
よく混同されがちなのが、ワイルドカード(パス名展開)との違いです。
以下の表で、その主な違いを確認しましょう。
| 機能 | 動作の仕組み | ファイル存在の要否 |
|---|---|---|
| ブレース展開 | 指定されたパターンを機械的に生成する | 不要(存在しない名前も作る) |
| ワイルドカード | 既存のファイル名とパターンを照合する | 必要(存在するファイルのみ対象) |
ブレース展開はあくまで「文字列の生成」であり、ファイルが実際に存在するかどうかは関係ありません。
一方、*.txtのようなワイルドカードは、カレントディレクトリにある実際のファイルを検索します。
注意点とトラブルシューティング
便利なブレース展開ですが、いくつか注意すべきルールがあります。
スペースの混入
先述した通り、ブレース内にスペースを入れると展開が機能しません。
# これは失敗する(スペースがあるため)
echo {one, two}
{one, two}
期待した展開が行われない場合は、まず余計なスペースが入っていないかを確認しましょう。
変数の利用に関する注意
ブレース展開は、変数の展開(Parameter Expansion)よりも先に行われます。
そのため、以下のような記述は期待通りに動作しません。
# 期待通りに動作しない例
END=5
echo {1..$END}
{1..5}
この場合、evalコマンドを使用するか、あるいはseqコマンドやC言語スタイルのforループを利用する必要があります。
大量展開による負荷
非常に大きな範囲(例:{1..1000000})を指定すると、メモリを大量に消費したり、引数の上限(ARG_MAX)を超えてエラーになったりする可能性があります。
大規模な処理を行う際は、展開結果がどれくらいの規模になるかを事前に考慮しましょう。
まとめ
Bashのブレース展開は、コマンドライン効率を極限まで高めてくれる非常に強力な機能です。
カンマ区切りによる単純なリスト生成から、シーケンス展開による連番生成、そして高度なネスト構造まで、その用途は多岐にわたります。
特にディレクトリ構造の構築やファイルのバックアップ作成といった日常的なタスクにおいて、その真価を実感できるはずです。
まずは簡単なechoコマンドでのテストから始めて、徐々に実務のコマンドに組み込んでみてください。
この記事で紹介したテクニックを活用し、より高速で正確なシェル操作を実現しましょう。
