Develop and Download Open Source Software

OpenSource Downloads

7-Zip  (4,208)  
HandBrake Japanese Language Version  (3,353)  
CrystalDiskInfo  (1,743)  
CotEditor  (1,120)  
CrystalDiskMark  (866)  
Boookends  (788)  
SMPlayer  (642)  
えこでこツール  (599)  
Tera Term  (595)  
10  FFFTP  (579)  
11  Cabos  (530)  
12  BathyScaphe  (494)  
13  ffdshow  (481)  
14  MergeDoc  (464)  
15  ギコナビ  (438)  
More >>

最近ブックマークされた記事

シェルスクリプトで役立つテキスト文字列のパターンマッチングの基礎

2009年01月06日 10:25 Peter Seebach 1 2 3 4 5

 シェルプログラミングでは、文字列に関する操作が大きな役割を果たすことになる。ここで言う文字列とは、連続した任意のキャラクタの並びで構成されるテキストのことで、具体例としてはインプットされるテキストやコマンドの引数などを考えればいい。そして、プロンプトへの応答入力、必要なファイル名の生成、コマンドの出力結果に対する処理を繰り返し実行させる際に必要となるのが、特定の文字列が特定のパターンと一致しているかという確認作業であり、これこそがパターンマッチングと呼ばれているプロセスである。そしてシェルには、パターンマッチング用の様々な機能が用意されているのだ。

本稿は最近出版された『Beginning Portable Shell Scripting』からの抜粋である。

 パターンマッチングの機能はgrepsedなど、多くのUnixユーティリティの形態で提供されている。通常この種のプログラムでは、正規表現(regular expression)と呼ばれるより強力なパターンマッチング機能が利用できる。正規表現はシェルパターンとは別系統の機能だが、効率的なシェルスクリプティングを行う上で必須の存在と考えて間違いないはずだ。ただし一口に正規表現と言っても、シェル内部にて共通化された正規表現機能が移植性のある形でサポートされている訳ではなく、シェルプログラムが依存する各種の外部ユーティリティが、それぞれ個別に正規表現を実装しているという状況になっている。

シェルパターン

 シェルパターン(shell pattern)は各種の状況にて利用される機能である。その代表例の1つがcaseステートメントであり、例えば下記のサンプルコードではstringpatternという2つのシェル変数を用いて、stringpatternに一致するかを判定している。

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)というシェル内部の処理(ファイル名展開とも呼ばれる操作)によって当該パターンに一致する名称を持つ任意のファイルに強制的に置き換えられるため、ここで意図するような試験は行えなくなってしまう。

最終更新:2009年03月08日 17:07