効率的なシェルスクリプティングを行う上で、文字列にかんする操作は非常に重要な役割を果たす。本稿では、これからシェルパターンや正規表現と呼ばれる強力なパターンマッチングを学ぼうとする方に向けたガイドをお届けする。
シェルプログラミングでは、文字列にかんする操作が大きな役割を果たすことになる。ここで言う文字列とは、連続した任意のキャラクタの並びで構成されるテキストのことで、具体例としてはインプットされるテキストやコマンドの引数などを考えればいい。そして、プロンプトへの応答入力、必要なファイル名の生成、コマンドの出力結果に対する処理を繰り返し実行させる際に必要となるのが、特定の文字列が特定のパターンと一致しているかという確認作業であり、これこそがパターンマッチングと呼ばれているプロセスである。そしてシェルには、パターンマッチング用のさまざまな機能が用意されているのだ。
本稿は最近出版された『Beginning Portable Shell Scripting』からの抜粋である。
パターンマッチングの機能はgrepやsedなど、多くのUNIXユーティリティの形態で提供されている。通常この種のプログラムでは、正規表現(regular expression)と呼ばれるより強力なパターンマッチング機能が利用できる。正規表現はシェルパターン(shell pattern)とは別系統の機能だが、効率的なシェルスクリプティングを行う上で必須の存在と考えて間違いないはずだ。ただし一口に正規表現といっても、シェル内部にて共通化された正規表現機能が移植性のある形でサポートされている訳ではなく、シェルプログラムが依存する各種の外部ユーティリティが、それぞれ個別に正規表現を実装しているという状況になっている。
シェルパターンは各種の状況で利用される機能である。その代表例の1つがcaseステートメントで、例えば後記のサンプルコードではstringとpatternという2つのシェル変数を用い、stringがpatternに一致するかを判定している。
case $string in
$pattern) echo "Match" ;;
*) echo "No match";;
esac
このサンプルでは$stringが$patternと一致した場合、シェルからのエコーとして“Match”が返されてcaseステートメントの分岐処理は終了する。そして一致していなかった場合に行われるのが$stringが*と一致するかの判定である。シェルパターンにおける*は任意の文字列との一致を意味するので、このサンプルでは$patternとの不一致時にシェルから返される出力は“No match”となる(仮に一致するパターンが複数存在してもcaseステートメントで実行される分岐処理は1つだけである)。
はじめてパターンマッチングを学習するユーザーの場合、先のサンプルコードを基とした試験用のシェルスクリプトを用意しておくと便利である。例えば、特定パターンに対する一連のマッチング試験を連続的に処理したければ、後記のようなスクリプトを用いればいい。
#!/bin/sh
pattern="$1"
shift
echo "Matching against '$pattern':"
for string
do
case $string in
$pattern) echo "$string: Match." ;;
*) echo "$string: No match." ;;
esac
done
実際にこのスクリプトを使用するには、同コードをpatternという名称で保存したファイルを実行可能にしておく必要があるが(chmod a+x pattern)、そうした準備後は後記のような一連の試験を簡単に行えるようになるはずだ。
$ ./pattern '*' 'hello'
Matching against '*':
hello: Match.
$ ./pattern 'hello*' 'hello' 'hello, there' 'well, hello'
Matching against 'hello*': hello: Match.
hello, there: Match.
well, hello: No match.
この場合の注意点として、個々の引数は一重引用符で囲む必要がある。特にパターン中で使うアスタリスク(*)などの特殊記号が引用符で囲まれていないと、グロビング(globbing)というシェル内部の処理(ファイル名展開とも呼ばれる操作)によって当該パターンに一致する名称を持つ任意のファイルに強制的に置き換えられるため、ここで意図するような試験は行えなくなってしまう。
新しいことをはじめる前には「Beginner's Guide」で知識を得てみませんか?
Copyright © 2010 OSDN Corporation, All Rights Reserved.