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

 一般的にパターンを用いたマッチングでは、最長マッチと呼ばれる一致判定が行われ、可能な限り広範な文字列とのマッチングが試みられる。しかしながら、アスタリスクのマッチ部に必要範囲以上のキャラクタが取り込まれた結果、当該パターン中の他のコンポーネントによるマッチングが妨げられるというように、アスタリスクによる最長マッチに起因して目的とする文字列全体とのマッチングが行えなくなる可能性も存在するのだ。例えばパターンb*を用いた文字列bananaに対するマッチングでは*部のコンポーネントがananaというテキストに一致するが、このパターンをb*naに変更すると*部が一致するテキストはanaとなるというように、*はマッチングが可能な範囲内にて最大限のキャラクタを取り込もうとするのである。またキャラクタクラスなどその他のパターンコンポーネントについては、通常の文字であるリテラルキャラクタおよび特殊記号の1つである疑問符のマッチングが最優先され、その残りの部分に対してアスタリスクによるマッチングが行われるようになっている。

 こうしたシェルパターンに付随する制限の一部は、ユーザ側の工夫によって回避することも可能であり、例えば複数のアイテムを並べたリストをシェル内にて格納したければ、対象となるアイテム群をa,b,cのように区切り文字を挟んでつなげればいい。下記のサンプルコードは、こうしたリストの具体的な使用例である(このcaseステートメントでは、指定した文字列とパターンが一致した場合にのみ出力用のコードを実行する)。

list=orange,apple,banana
case $list in
*apple*)  echo "How do you like them apples?";;
esac

How do you like them apples?

 ただしこのサンプルスクリプトには、一致のチェックが厳密でないことに起因したバグが潜んでいる。具体的な問題点は、下記のような若干の変更を加えることで明確化するはずだ。

list=orange,crabapple,banana
case $list in
*apple*)  echo "How do you like them apples?";;
esac

How do you like them apples?

 これは先に触れたアスタリスクによる最長マッチに起因する問題であり、その対策としては、最長マッチの影響範囲と区切り記号のカンマの位置関係なども考えなくてはならない。一見すると、下記のようにパターン本体に区切り記号を追加すると上手く行きそうだが、今度はリストの両端に位置するアイテムには一致できなくなってしまう。

list=orange,apple,banana
case $list in
*,orange,*)  echo "The only fruit for which there is no Cockney slang.";;
esac

[no output]

 この問題の最終的な対処法としては、下記のようにリストの展開時に意図的に区切り記号を追加しておくことが考えられる。

list=orange,apple,banana
case ,$list, in
*,orange,*)  echo "The only fruit for which there is no Cockney slang.";;
esac

The only fruit for which there is no Cockney slang.

 こうして得られる$listの展開結果はカンマが両端に置かれた文字列となり、当該リストのアイテムすべてがカンマに挟まれた状態となるので、先のパターンによるマッチングは問題なく実行可能となる。

Linux.com 原文(2008年12月26日)

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