目次  I Love CUI

パターンマッチ

Linux には複数のファイルや文字列をパターンで表現する機能が満載です。パターンを利用すると共通の性質をもつ複数のファイルの処理や、パターンにマッチする複数の語句の検索が効率的にできます。シェルのワイルドカードや、grep の正規表現に見られるパターン処理を眺めてみましょう。

ワイルドカード

シェルのコマンドライン上では、ワイルドカードを用いることで複数のファイルを一括して扱うことができます。'*' というワイルドカードは、0 個以上の文字列に合致するファイルすべてに展開することができます。例えば ls * とすると、カレントディレクトリ上のすべてのファイルのリストを取ることができます。

~/markdown/simple$ ls *
example.md       makingtool.md  new               simple.md         vmd
index.html       markdown.html  pattern_match.md  tag_example.html
index.md         markdown.md    send              tag_example.md
makingtool.html  mk             simple.html       template.md

また、ls *.md とすると、カレントディレクトリの拡張子が .md のファイルのリストを表示できます。

~/markdown/simple$ ls *.md
example.md  makingtool.md  pattern_match.md  tag_example.md
index.md    markdown.md    simple.md         template.md

さらに、ls *down* とするとファイル名の中に 'down' という文字列のあるファイルのリストを表示できます。

~/markdown/simple$ ls *down*
markdown.html  markdown.md

[ab] は文字クラスを示します。すなわち文字 'a' か、または文字 'b' が含まれているパターンです。ls [et]* とすると、冒頭に 'e' か 't' がついているファイルを検索します。

~/markdown/simple$ ls [et]*
example.md  tag_example.html  tag_example.md  template.md

また、ls [!et]* とすると冒頭に 'e' や 't' を含まないファイルのリストを表示します。

~/markdown/simple$ ls [!et]*
index.html       makingtool.md  mk                send         vmd
index.md         markdown.html  new               simple.html
makingtool.html  markdown.md    pattern_match.md  simple.md

{index,down} は、カーリーブレースの中の文字列のいずれかにマッチする場合です。ls *{index,down}* はファイル名の中に index という文字列または down という文字列が含まれるファイルを表示します。

~/markdown/simple$ ls *{index,down}*
index.html  index.md  markdown.html  markdown.md

? は1文字を表します。?????.md は5文字の名前で拡張子が .md のものを表します。

~/markdown/simple$ ls ?????.md
index.md

正規表現

grep は検索コマンドです。キーワードの文字列がファイルの中に含まれているかどうかを検索します。grep の第1引数にはキーワード、第2引数には検索する文書を渡します。次の例は body という文字列を index.md という文書から検索しています。

~/markdown/simple$ grep body index.md
<style>body {width: 600px; margin: auto;}</style>
<body>
</body>

第1引数の検索文字には文字列だけでなく正規表現を渡すこともできます。正規表現ではメタキャラクタを使って、文字列のパターンを表現します。メタキャラクタは文字ですが、文字そのものではなく文字列に関するパターンを表します。メタキャラクタについてについて、代表的なものを次に示します。

.

. は任意の1文字を表します。" .... " は4文字の前後にスペースが来るパターンにマッチします。正規表現には * の様にシェルのワイルドカードと同じ文字が使われていたりするので、そのままだとシェルで展開されてしまいます。grep に確実に正規表現を渡すためには、引用符で囲んで文字列として渡します。

~/markdown/simple$ grep " .... " index.md
<title>Simple HTML Contents</title>
[I Love CUI](https://userweb.mnet.ne.jp/tnomura/)

*

* は直前の1文字またはパターンの0回以上の繰り返しにマッチします。"60*" は 6 のあとに 0 が0回以上現れるパターンにマッチします。

~/markdown/simple$ grep "60*" index.md
<style>body {width: 600px; margin: auto;}</style>

^ と $

^ は行頭、$ は行末にマッチします。"L$" は行末に 'L' があるパターンにマッチします。

~/markdown/simple$ grep "L$" index.md
# Simple HTML

文字クラス

[abc] は文字クラスです、ブラケットの中の1文字にマッチします。* と組み合わせて "[0-9][0-9]*" の様にパターンを作ることができます。これは1文字以上の数字を表しています。

~/markdown/simple$ grep "[0-9][0-9]*" index.md
<meta charset="utf-8">
<style>body {width: 600px; margin: auto;}</style>

正規表現のメタ文字は他にもありますが、ここでは扱いません。これらのメタ文字と一般の文字列を組み合わせることで、数字だけを抜き出したり、複数の文字列にマッチさせたりなど多彩な文字列のパターン処理ができます。ここではほんの一例を述べました。

また、この記事で強調したかったのは、シェルのワイルドカード展開のメタ文字と正規表現のメタ文字が重複しているため grep に渡す正規表現によっては期待したのもとは違う動作をすることがあるということです。grep で正規表現を用いるときは、シェルのワイルドカードと区別するために、引用符で囲って文字列として与えるということが要点です。

いずれにしても、Linux では文字列のパターンをフルに活用することが多いので、パターンマッチについての知識を整理しておくことは有益です。

戻る