3.2 レッスン 2
Certificate: |
Linux Essentials |
---|---|
Version: |
1.6 |
Topic: |
3 コマンドラインの力 |
Objective: |
3.2 ファイルからデータを検索して取得する |
Lesson: |
2 of 2 |
はじめに
このレッスンでは、テキストを操作するために使用するツールを見ていきます。システム管理者やプログラムは、繰り返し発生する情報を自動的に識別して監視するために、これらのツールを使います。
grep
でファイル内を検索する
このレッスンで説明する最初のツールは grep
コマンドです。grep
は “global regular expression print” (汎用正規表現の表示)というフレーズの略語であり、その主な機能は、指定されたパターンをファイル内で検索することです。このコマンドは、指定されたパターンを含む行を赤で強調表示して出力します。
$ grep bash /etc/passwd root:x:0:0:root:/root:/bin/bash user:x:1001:1001:User,,,,:/home/user:/bin/bash
ほとんどのコマンドと同様に、grep
はオプションを使用して微調整することができます。最も一般的なものは次のとおりです。
-i
-
大文字と小文字を区別せずに検索します
-r
-
再帰的に検索します(指定されたディレクトリとそのサブディレクトリ内のすべてのファイルを検索します)
-c
-
検索で一致した数をカウントします
-v
-
一致条件を反転し、検索パターンに一致しない行を表示します
-E
-
拡張正規表現を有効にします(
|
、+
、?
などのメタ文字を使用する場合に必要です)
grep
には、他にも多くの便利なオプションがあります。詳細については、manページを参照してください。
正規表現
2番目のツールは非常に強力です。ファイル内のテキストのパターンを記述するために使用され、正規表現 と呼ばれます。正規表現は、組み立てた(文字の)パターンに応じて、テキストファイルからデータを抽出するのに非常に役立ちます。正規表現は、シェルスクリプトや、PerlやPythonなどの高レベル言語でプログラミングするときに使用されます。
正規表現を使用する場合、選択したい文字の並び(文字列)に一致するように、個々の文字 とパターンを記述することがとても大切です。ほとんどのパターンでは、文字、数字、句読点、その他の記号など、通常のASCII記号を使用しますが、他の言語のテキストと一致させるためにUnicode文字を使用することもできます。
以下に、パターンの指定に使用する、正規表現のメタ文字について説明します。
.
-
任意の1文字と一致 (改行は除く)
[abcABC]
-
角括弧内の任意の1文字と一致
[^abcABC]
-
角括弧内の文字を除く任意の1文字と一致
[a-z]
-
範囲内の任意の1文字と一致
[^a-z]
-
範囲外の任意の1文字と一致
sun|moon
-
リストされた文字列のいずれかに一致
^
-
行の先頭
$
-
行の末尾
grep
には、正規表現のすべての機能が実装されています。上記の例では、単語を引用符で囲んでいませんが、シェルがメタ文字を解釈しないようにするために、複雑なパターンをダブルクオート(" ")で囲むことがお勧めです。実習では、正規表現を表記するときに、ダブルクオートを使用します。以前のレッスンで学習したように、他のクオート記号も通常通り使用できます。
例では、正規表現の機能を述べていきます。ファイル内にデータを入れるために、次のコマンド群で、text.txt
ファイルにいくつかの文字列を追加します。
$ echo "aaabbb1" > text.txt $ echo "abab2" >> text.txt $ echo "noone2" >> text.txt $ echo "class1" >> text.txt $ echo "alien2" >> text.txt $ cat text.txt aaabbb1 abab2 noone2 class1 alien2
最初の例は、ファイルの検索に、正規表現を使用した場合と、使用しない場合の組み合わせです。正規表現を完全に理解するには、違いを示すことが非常に重要です。最初のコマンドは、行の任意の場所で一致する文字列を検索しますが、2番目のコマンドは、角括弧内の文字のいずれかを含む文字列を検索します。したがって、コマンドの結果が異なります。
$ grep "ab" text.txt aaabbb1 abab2 $ grep "[ab]" text.txt aaabbb1 abab2 class1 alien2
2番目の例は、行の始まりと終わりを示すメタ文字の例を示しています。式の適切な場所に2つのメタ文字を指定することが非常に重要です。行の先頭を指定する場合はメタ文字をワードの前に置く必要があり、行の末尾を指定する場合はメタ文字をワードの後に置く必要があります。
$ grep "^a" text.txt aaabbb1 abab2 alien2 $ grep "2$" text.txt abab2 noone2 alien2
前の例で説明したメタ文字に加えて、正規表現には、直前のパターンの繰り返しを意味するメタ文字もあります。
*
-
直前のパターンの0回以上の繰り返し
+
-
直前のパターンの1回以上の繰り返し
?
-
直前のパターンに一致しないか、1回だけ一致する
繰り返しメタ文字を使用する次のコマンドでは、文字列 ab
に続く、任意の1文字の1回以上の繰り返しを探します。grep
は文字列 aaabbb1
の abbb
部と、 abab2
を見つけて返します。文字 +
は、拡張 正規表現のメタ文字なので、grep
コマンドには -E
オプションを指定する必要があります。
$ grep -E "ab.+" text.txt aaabbb1 abab2
ほとんどのメタキャラクターは一目瞭然ですが、初めて使用する場合は注意が必要です。前の例は、正規表現の機能のほんの一部に過ぎません。上記の表のすべてのメタ文字を試して、それらがどのように機能するかをよく理解してください。
演習
grep
を使用して /usr/share/hunspell/en_US.dic
ファイルから、以下に一致する行を抽出しましょう。
(訳注: 上記のファイルはhunspell(OpenOffice.orgが提供するスペルチェッカー)に含まれているものです。)
-
行のどこかに単語
cat
を含むすべての行 -
次の文字のいずれも含まないすべての行:
sawgtfixkgts
。 -
任意の3文字と文字列
dig
で始まるすべての行 -
少なくともひとつの
e
で終わるすべての行 -
次のいずれかの単語を含むすべての行:
org
、kay
、またはtuna
-
1文字ないし0文字の
c
から始まり、文字列abi
が続く行の数
発展演習
-
“含める” にある単語に一致し、 “含めない” にある単語に一致しない正規表現を考えましょう。
-
含める:
pot
,spot
,apot
含めない:
potic
,spots
,potatoe
-
含める:
arp99
,apple
,zipper
含めない:
zoo
,arive
,attack
-
含める:
arcane
,capper
,zoology
含めない:
air
,coper
,zoloc
-
含める:
0th/pt
,3th/tc
,9th/pt
含めない:
0/nm
,3/nm
,9/nm
-
含める:
Hawaii
,Dario
,Ramiro
含めない:
hawaii
,Ian
,Alice
-
-
ファイル内を検索する、別のコマンドは何でしょう? そのコマンドの(grepにはない)追加の機能は何ですか?
-
前のレッスンを振り返っていずれかの例を使用し、
grep
を使用して、コマンドの出力内で特定のパターンを探してみましょう。
まとめ
このレッスンでは、次のことを学びました。
-
正規表現のメタ文字
-
正規表現でパターンを指定する方法
-
ファイル内を検索する方法
演習で使用したコマンド:
grep
-
ファイル内から、文字や文字列を検索する
演習の解答
grep
を使用して /usr/share/hunspell/en_US.dic
ファイルから、以下に一致する行を抽出しましょう。
(訳注: 上記のファイルはhunspell(OpenOffice.orgが提供するスペルチェッカー)に含まれているものです。)
-
. 行のどこかに単語
cat
を含むすべての行$ grep "cat" /usr/share/hunspell/en_US.dic Alcatraz/M Decatur/M Hecate/M ...
-
次の文字のいずれも含まないすべての行:
sawgtfixkgts
。$ grep -v "[sawgtfixk]" /usr/share/hunspell/en_US.dic 49269 0/nm 1/n1 2/nm 2nd/p 3/nm 3rd/p 4/nm 5/nm 6/nm 7/nm 8/nm ...
-
任意の3文字と文字列
dig
で始まるすべての行$ grep "^...dig" /usr/share/hunspell/en_US.dic cardigan/SM condign predigest/GDS ...
-
少なくともひとつの
e
で終わるすべての行$ grep -E "e+$" /usr/share/hunspell/en_US.dic Anglicize Anglophobe Anthropocene ...
-
次のいずれかの単語を含むすべての行:
org
、kay
、またはtuna
$ grep -E "org|kay|tuna" /usr/share/hunspell/en_US.dic Borg/SM George/MS Tokay/M fortunate/UY ...
-
1文字ないし0文字の
c
から始まり、文字列abi
が続く行の数$ grep -cE "^c?ati" /usr/share/hunspell/en_US.dic 3
発展演習の解答
-
“含める” にある単語に一致し、 “含めない” にある単語に一致しない正規表現を考えましょう。
-
含める:
pot
,spot
,apot
含めない:
potic
,spots
,potatoe
答え:
pot$
-
含める:
arp99
,apple
,zipper
含めない:
zoo
,arive
,attack
答え:
p+
-
含める:
arcane
,capper
,zoology
含めない:
air
,coper
,zoloc
答え:
arc|cap|zoo
-
含める:
0th/pt
,3th/tc
,9th/pt
含めない:
0/nm
,3/nm
,9/nm
答え:
[0-9]th.+
-
含める:
Hawaii
,Dario
,Ramiro
含めない:
hawaii
,Ian
,Alice
答え:
^[A-Z]a.*i+
-
-
ファイル内を検索する、別のコマンドは何でしょう? そのコマンドの(grepにはない)追加の機能は何ですか?
sed
コマンド。このコマンドは、ファイル内の文字列を検索し、別の文字列で置き換えることができます。 -
前のレッスンを振り返っていずれかの例を使用し、
grep
を使用して、コマンドの出力内で特定のパターンを探してみましょう。本コースの「発展演習」から回答の1つを取得し、グループのアクセス許可として読み取り、書き込み、および実行が許可された行を探しました。選択したコマンドと作成したパターンに応じて、答えは異なる場合があります。
$ cat contents.txt | tr -s " " | grep "^....rwx"
この解答例では、
grep
コマンドが、別のコマンドから入力を受け取り、出力された情報をフィルタリングできることが分かります。