Jump to content 日本-日本語

製品  >  ソフトウェア  >  HP-UX   >  Knowledge-on-Demand  >  UNIXの教科書 応用編

UNIXの教科書 応用編
〜はじめよう! WindowsとLinuxからのステップアップ〜

第1日目:grepコマンドと正規表現

HP-UX/Integrityサーバー お問い合せ
コンテンツに進む
第1日目:grepコマンドと正規表現
UNIXの教科書 応用編〜はじめよう! WindowsとLinuxからのステップアップ〜 1日目
grepコマンドの基本的な使い方
正規表現の基礎を知る

2時間目:正規表現の基礎を知る

さて、1時間目ではgrepコマンドを使用して、テキストファイルから指定した文字列を含む行を取り出す方法に説明しました。実は、grepコマンドの醍醐味は「正規表現」と呼ばれるパターンを使って、柔軟な文字列の指定ができることにあります。正規表現は複雑なパズルの世界に似て実に奥深いものですが、この時間では、その入門編として基本的な使い方について説明します。

正規表現とは

まずは、正規表現を使った簡単な例を示しましょう。1時間目の例に使った、テキストファイル「mail.txt」を思い出してみましょう。

makoto otsu,mako@example.com,41
yamada taro,taroy@example.com,33
oyamada hana,oyama33@example.jp,44
kataoka ichiro,k-ichi@example.com,43
oka hanako,hana41@example.com,51

このファイルの各行の最初のフィールドには名前が格納されています。この中から「oka」という名前の人を取り出そうと、次のように実行したとします。

$ grep oka mail.txt 【Enter】
kataoka ichiro,kichi@example.com,43
oka hanako,hana41@example.com

結果として2行が表示されました。途中に「oka」を含む「kataoka」という名前も取り出されてしまったからです。
この場合、次のようにすると、行頭が「oka」で始まる行だけが表示されます。

$ grep "^oka" mail.txt 【Enter】
oka hanako,hana41@example.com

上記の「^oka」というのが正規表現のパターンです。想像が付くかもしれませんが、「^」は行の先頭を表す正規表現の「メタキャラクタ」(特殊文字)です。これで先頭が「oka」から始まる行だけが取り出されます。

タックス君:
「^」が行の先頭なら、行の終わりは?
タックス君
マリー先生
マリー先生:
行の終わりは「$」で表すの。次の例を見てね。

$ grep "33" mail.txt 【Enter】 ←「33」を含む行を表示
yamada taro,taroy@example.com,33
oyamada hana,oyama33@example.jp,44
$ grep "33$" mail.txt 【Enter】 ←行の終わりが「33」の行を表示
yamada taro,taroy@example.com,33

任意の1文字を表すピリオド「.」

シェルのワイルドカードを思い出してみましょう。シェルのワイルドカードでは「?」が任意の1文字を表しました。それに対して、正規表現ではピリオド「.」が改行を除く任意の1文字を表します。次のようなファイル「sample1.txt」があるとします。

HP-UX v11
11i v3
1.3 V1
v11.0
11i v2
00va

このファイルから、たとえば行末が「v<任意の文字>」という文字列を含む行を取り出すには、パターンに「v.$」を指定して次のようにします。

$ grep "v.$" sample1.txt 【Enter】
11i v3
11i v2
00va

タックス君:
ピリオド「.」そのものを含む文字列を指定するにはどうすればよいのですか?
タックス君
マリー先生
マリー先生:
その場合、ピリオド「.」の前に「\」を記述すると、ピリオド「.」を通常の文字として扱うの。たとえば、「.0」という文字列を含む行を取り出すには、次のようにすればいいわ。

$ grep "\.0" sample1.txt 【Enter】
v11.0

前にも説明したように、このように「\」によってピリオドのような特殊文字の働きを打ち消すことを「エスケープする」というの。


直前の文字の繰り返し

アスタリスク「*」は、直前の文字(もしくは直前の正規表現)の0回以上の繰り返しにマッチします。このとき、「1回以上」ではなく「0回以上」という点に注意してください。たとえば、次のようなテキストファイル「sample2.txt」があるとします。

HP-UX
HPP-UX
H-UX

パターンに「HP*-UX」を指定してgrepコマンドを実行すると、すべての行が表示されます。最後の「H-UX」のように「P」を含まない行まで表示される点に注目してください。「P*」は空の文字列にもマッチするからです。

$ grep "HP*-UX" sample2.txt 【Enter】
HP-UX
HPP-UX
H-UX

四色君:
あれ? シェルのワイルドカードでは、「*」は0文字以上の任意の文字列を表しましたよね。
四色君
マリー先生
マリー先生:
そうね。正規表現では、「*」の意味がシェルのワイルドカードと異なるので注意してね。正規表現では0文字以上の任意の文字列は「.」と「*」をつなげて「.*」で表すの。あと、「*」がシェルによって展開されないように引数をかならずダブルクォーテーション「"」で囲む点にも注意してね。

いずれかの文字を表す

「[ ]」内に文字を並べて記述すると、その中のいずれかの1文字とマッチします。このような指定方法を「文字クラス」などと呼びます。たとえば[ab]は「a」か「b」にマッチします。なお、[0123456789]のような連蔵した文字は、最初と最後の文字をハイフン「-」で繋いで[0-9]のように指定することもできます。
たとえば、sample1.txtから「行頭が2桁の数字で始まる行」は、次のようにして取り出せます。

$ grep "^[0-9][0-9]" sample1.txt 【Enter】
11i v3
11i v2
00va

このとき、行頭を表すの使用した「^」ですが、文字のリストの先頭に付けると、否定を表します。したがって、次の例は「行頭が数字以外で、2文字目が数字の行」を表示します。

$ grep "^[^0-9][0-9]" sample1.txt 【Enter】
v11.0

名前付き文字クラス

文字クラスには、名前で文字を指定できる「名前付き文字クラス」と呼ばれる表記も用意されています。

<表1:名前付き文字クラスの例>

[:alpha:]

文字

[:upper:]

大文字

[:lower:]

小文字

[:digit:]

10 進数の数字

[:alnum:]

文字あるいは 10 進数の数字

[:blank:]

空白文字


たとえば、数字は「0-9」の代わりに[:digit:]と表記できます。つまり、sample1.txtから、「行頭が2桁の数字で始まる行」を取り出す例は次のように記述できます。

$ grep "^[[:digit:]][[:digit:]]" sample1.txt 【Enter】
11i v3
11i v2
00va

grepファミリー

grepには、「egrep」と「fgrep」という仲間のコマンドが用意されています。これらをまとめてgrepファミリーと呼びます。egrepは「Extend grep」の略で、拡張されたパターンが指定可能です。fgrepは「Fixed grep」の略で正規表現の使えないgrepです。なお、これらはそれぞれ「grep -E」、「grep -F」を実行しても同じです。egrepおよびfgrepは将来サポートされなくなる可能性があるため、「grep -E」、「grep -F」の使用が推奨されています。

たとえば、「grep -E」で使用可能な拡張正規表現では、新たに「+」が特殊記号として使用できます。通常の正規上限では「*」は前の文字の1回以上の繰り返しでしたが、「+」は前の文字の1回以上の繰り返しを表します。
次に、「*」と「+」の相違を示す例を示します。

$ grep -E "HP*-UX" sample2.txt 【Enter】 ←「*」を使用
HP-UX
HPP-UX
H-UX ←「H」と「-」の間になにもなくてもマッチしてします。
$ grep -E "HP+-UX" sample2.txt 【Enter】 ←「+」を使用
HP-UX
HPP-UX

タックス君:
「grep -E」、つまりegrepが一番高機能なら、ほかのgrepの仲間のいらないような気がするですが
タックス君
マリー先生
マリー先生:
grepは機能が豊富で柔軟なパターンが記述できるのは、指定できるメタキャラクタが増えているからなの。それらの、メタキャラクタを覚えておかないと、間違ってメタキャラクタを普通の文字として使ってしまってしまう可能性もあるわけ。また、メタキャラクタを文字として扱うときにその都度エスケープするのも面倒でしょう。
たとえば、次のような「sample3.txt」から、「...*」とい文字列を含む行を取り出したいとしましょう。

abcde
a...*a
sample

この場合、grepおよび「grep -E」では、次のようにしてピリオド「.」をエスケープしなければならないの。

$ grep "\.\.\.\*" sample3.txt 【Enter】
a...*a

それに対して、「grep -F」、つまりfrepでは正規表現の特殊文字を気にしないで次のようにできるわけ。

$ grep -F "...*" sample3.txt 【Enter】
a...*a


練習問題

第1問:/etc/servicesファイルから文字列「 23/」(*注 最初がスペース)を含む行を取り出すコマンドはどれか?

a) grep 23/ /etc/services
b) grep -i 23 /etc/serices
c) get 23/ /etc/services
d) grep " 23/" /etc/services
正解はこちら
d) grep " 23/" /etc/services
スペースを含む文字列を検索するには全体をダブルクォーテーション「"」で囲む。
また、次のコマンドでも同じ結果が得られる。
grep \ 23/ /etc/services

第2問:/etc/servicesファイルから、文字列「echo」を含み、かつ、文字列「udp」を含まない行を取り出すコマンドはどれか

a) grep -e echo -e udp /etc/services
b) grep echo /etc/services | grep udp
c) grep echo udp /etc/services
d) grep echo /etc/services | grep -v udp
正解はこちら
d) grep echo /etc/services | grep -v udp
複数の条件で絞り込むにはパイプ「|」を使用してgrepコマンドを組み合わせる。また、指定した文字列を含まない行を取り出すには「-v 文字列」オプションを指定する。

第3問:次のようなテキストファイル「sample4.txt」から、数字だけの行を表示するコマンドはどれか?

111 11
aa22
11bb
101aa2
2222
555
bb77
a) grep "[[:digit:]][[:digit:]]*" sample4.txt
b) grep "^1-9$" sample4.txt
c) grep "^[[:digit:]][[:digit:]]*$" sample4.txt
d) grep "^[[:digit:]]*$" sample4.txt
正解はこちら
c) grep "^[[:digit:]][[:digit:]]*$" sample4.txt
名前付き文字クラスでは数字は「[:digit:]」と記述する。また、文頭は「^」、文末は「$」、前の文字の0回以上の繰り返しは「*」と記述できる。したがって(c)が正解。(d)だと空行も出力されてしまう点に注意してほしい。
また、次の拡張機能を持ったegrepコマンドでも同じ結果が得られる。
egrep "^[0-9]+$” sample4.txt

第4問:sample4.txtファイルから、先頭が「1から4の間の数字」で始まらない行を表示するコマンドはどれか?

a) grep "^[^1-4]" sample4.txt
b) grep "^[1-4]" sample4.txt
c) grep "^[^[:digit:]]" sample4.txt
d) grep -F "^[^1-4]" sample4.txt
正解はこちら
a) grep "^[^1-4]" sample4.txt
[文字の並び]の先頭に「^」を記述すると、否定を表す。つまり「[^1-4]」は「1から4の間の数字」以外の文字にマッチする。

連載記事一覧 戻る 1  |  2

教科書シリーズ 「UNIXの教科書」 「HAクラスターの教科書」 連載記事一覧

UNIXの教科書「基礎編」

第1日目:ログインしてコマンドを実行してみる
第2日目:ディレクトリやファイルを操作してみる
第3日目:シェルの基本を知る
第4日目:ファイルの基本操作
第5日目:viエディタの操作(基本編)
第6日目:リダイレクションとパイプを活用する
期末試験

UNIXの教科書「応用編」

第1日目:grepコマンドと正規表現
第2日目:ファイルの検索
第3日目:viエディタの操作(活用編)
第4日目:ファイルの圧縮とアーカイブ
第5日目:ジョブとプロセスの操作
第6日目:シェルの環境設定
第7日目:シェルスクリプトでより便利に
期末試験

UNIXの教科書「運用編」

第1日目:ユーザーの管理
第2日目:ファイルの安全管理(その1)
第3日目:ファイルの安全管理(その2)
第4日目:ネットワークの基本を理解する
第5日目:ネットワーク関連のコマンド
第6日目:システム情報の表示
期末試験 New!

HAクラスターの教科書

第1日目:ハードウェア構成を知る
第2日目:ネットワークを設定する
第3日目:共有ディスクを構成する
第4日目:HAクラスターを構成する
第5日目:パッケージを構成する
第6日目:障害テストを実施する
期末試験

 その他の連載記事


本ページの内容は執筆時の情報に基づいており、異なる場合があります。

お問い合わせ

ご購入前のお問い合わせ


ご購入後のお問い合わせ

HPEサポートセンター
製品の標準保証でご利用いただける無償のサービスです。

ショールーム

ショールーム 導入をご検討のお客様へ
業務アプリケーションの継続・標準化・開発性とシステム担当者様、システム開発者様が抱える悩み・疑問に対する解決策実体験して頂けます。
印刷用画面へ
プライバシー ご利用条件・免責事項