【grep特集】ざっくりわかるシェルスクリプト4

はじめに

grep(グレップ)コマンド。UNIX/Linuxにおいてこれほど歴史あり、強力なコマンドはありません。そして多くのユーザーがこのコマンドを使いこなしています。Webサーバーのログから特定のユーザーのみを抽出するちいさなスクリプトから、膨大なシステムログからロケットの軌道修正を計算する処理プログラムなど、半世紀もの長い間、一糸乱れることなく動き続けています。

「grep」コマンドは、文字列、またはファイル内のをテキストを検索するための便利で不可欠なコマンドです。
「grep」コマンドの正式な名称は「“global regular expression print.”」です。
このコマンドの名前は、正規表現に基づいてコンテンツを検索できる「g / re / p」に由来しています。
「grep」コマンドには、ファイル内の文字列またはテキストを検索するため、複数の方法が用意されている。

以下に「grep」コマンドを使用するいくつかの構文を示します。

カラー表示

まず、grep コマンドをカラー表示にしてみます。
以下のコマンドで、~/.bashrc を開きます。

$ vim ~/.bashrc

以下の2行を ~/.bashrc に追記して保存して下さい。

alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias ls='ls -FG'; 

grep/egrep/fgrep そしてついでに lsコマンドもカラー表示に変更します。変更したら ~/.bashrcを以下のコマンドで再読込します。

$ . ~/.bashrc
$ 

では、grep コマンドを使ってみます。
ここでは /etc/passwordファイルをgrepしてrootを検索してみます。

$ grep root /etc/password
$

構文

次の「grep」コマンドは、ファイル内の特定の文字列またはテキストを検索するために使用されます。

$ grep 検索文字列 ファイル名

次の「grep」コマンドは、複数のファイル内の特定の文字列またはテキストを検索するために使用されます。

$ grep 検索文字列 filename1 filename2 filename3
$ 

次は、空白を含む文字列を検索します。この場合はシングルクォーテーション「'」、またはダブるクォーテーション「"」で文字列を囲む必要があります。

$ grep "検索文字列 検索文字列" filename1
$ 

次の「grep」コマンドは、ファイル内の特定のオプションを含む文字列を検索するために使用されます。「 grep」コマンドでは、さまざまな目的でさまざまなオプションが使用されます。
ここでは「-v」を紹介します。「-v」オプションは、検索文字列を含まない行を抽出するオプションです。
このオプションは、非常に多くの場面で利用されます。

$ cat /etc/passwd | head
##
# User Database
#
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
bash-5.1$ cat /etc/passwd | head
##
# User Database
#
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
$
bash-5.1$ cat /etc/passwd | head | grep "User"
# User Database
$
$ cat /etc/passwd | head | grep -v "User"
##
#
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
$ 

まず、

$ cat /etc/passwd
$

で、/etc/passwd ファイルをcat します。
catするというのは、ファイル内容を出力すると言う意味になります。さらに、

$ cat /etc/passwd | head 
$

の、headは、出力された /etc/passwd ファイルの冒頭10行を抽出するというコマンド「head」です。「head」コマンドで -n5 オプションをつけることで冒頭5行目とすることもできます。

$ cat /etc/passwd | head -n5
$

シェルスクリプトは、「| 」パイプでコマンドを連ねることで、前のコマンドに続いて、さらにコマンドの出力結果を絞り込むことができます。
次のコマンドは、/etc/passwd ファイルを catコマンドで表示し、headコマンドで冒頭10行を抽出、さらに grep -v コマンドで User を除く行を出力します。

$ cat /etc/passwd | head | grep -v "User"

「 grep -v 」コマンドは、指定した文字列を含まない行を抽出するという意味です。

-v をつけなければ、User という文字列を含む文字列が抽出されることになります。

さらにgrepには強力な「-i」オプションがあります。
「-i」オプションは、検索文字列の大文字、小文字を区別せずに抽出します。

$ cat /etc/passwd | head | grep -iv "user"
##
#
# Note that this file is consulted directly only when the system is running
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
$
ヒント
grep コマンドで最も使われる書式は
$ cat <ファイル名> | grep “検索文字列”
です。
以下、'-v' ‘-i’ 二つのオプションをパイプで駆使すればgrepコマンドを使いこなしていると言っても過言ではありません。
# -v 除外
$ cat <ファイル名> | grep -v "検索文字列"

# -i 大文字小文字を区別しない
$ cat <ファイル名> | grep -i "検索文字列"

一致する文字列を検索

では手始めに、次のコマンドで、Customers.txtファイルの内容を表示します。以下の内容をCustomers.txtとして保存して下さい。

ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966

Customers.txtを表示します。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$

次の「grep」コマンドは、Customers.txtファイルのテキストから「Ali」を含む語句を検索します。
検索テキストがファイルに存在する場合、テキストを含む行が印刷されます。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep Ali
45  Minhaz Ali      ali@gmail.com       +8801190761212
$

次の「grep」コマンドは、Customers.txtファイルのテキスト「 MalihaChowdhury 」を検索します。検索テキストがファイルに存在する場合、テキストを含む行が印刷されます。

$ cat Customers.txt | grep 'Maliha Chowdhury'
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
$

一致しない文字列のみを検索

「grep」コマンドの-vオプションは、ファイルから一致しない文字列を検索するために使用されます。この例では、-vオプションを指定した「grep」コマンドを使用して、最初の例で作成したCustomers.txtファイルから一致しない文字列を検索しています。

次のコマンドは、customers.txtファイルの内容を表示します。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -v 'Abir'
ID  Name            Email           Phone
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
ヒント
-vオプションは、ファイルから一致しない文字列を検索するために使用されます。
検索文字列を除外して検索する場合は、'-v’オプションを使います。
$ cat <ファイル名> | grep -v “検索文字列”

大文字と小文字を区別しない一致の検索文字列

「grep」コマンドは、デフォルトで大文字と小文字を区別してファイルから文字列を検索します。
「grep」コマンドの ‘-i’ オプションは、大文字と小文字を区別しない方法でファイルから文字列を検索するために使用されます。
この例では、'-i' オプションを指定した「grep」コマンドを使用して、前に作成したCustomers.txtファイルから大文字と小文字を区別しない方法で特定の文字列を検索しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -i 'minhaz'
45  Minhaz Ali      ali@gmail.com       +8801190761212
$
ヒント
文字が大文字または小文字の文字列を含む1つ以上の行がファイルに存在する場合、その行が出力されます。
大文字小文字を区別しないで検索する場合は、'-i’オプションを使います。
$ cat <ファイル名> | grep -i “検索文字列”

単語全体のみを検索

「grep」コマンドの ‘-w’ オプションは、大文字と小文字を区別してファイルから単語全体を検索するために使用されます。
この例では、'-w' オプションを指定した「grep」コマンドを使用して、最初の例で作成されたCustomers.txtファイルから単語全体を検索しています。

次のコマンドは、customers.txtファイルの内容を表示します。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$

次の「grep」コマンドは、文字列「Ma」を含むテキストファイルの行を検索します。ファイルのいずれかの行に文字列「Ma」が含まれている場合、その行が出力されます。

$ cat Customers.txt | grep 'Ma'
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$

次の「grep」コマンドは、「Ma」という単語を含むテキストファイルの行を「正確」に検索します。
ファイルのいずれかの行に「Ma」という単語が正確に含まれている場合、その行が出力されます。
「Ma」という単語がないため、出力されません。

$ cat Customers.txt | grep -w 'Ma'
$ 

次の「grep」コマンドは、「Maliha」という単語を含むテキストファイルの行を正確に検索します。
ファイルのいずれかの行に「Maliha」という単語が正確に含まれている場合、その行が出力されます。

$ cat Customers.txt | grep -w 'Maliha'
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
$
ヒント
‘-w’ オプションと検索語「Ma」を指定した「grep」コマンドは、テキストファイルに「Ma」という単語が含まれていないため、何も返しませんでした。
-wオプションと検索語「Maliha」を指定した「grep」コマンドは、「Maliha」という単語を含むファイルの5行目を返しました。
‘-w’ オプションは正確な単語を検索対象とするオプションです。

現在のディレクトリで複数のファイルを検索する

「grep」コマンドは、ファイル内の特定のコンテンツを検索し、検索文字列またはパターンに基づいて現在のディレクトリ内の複数のファイルを検索するために使用されます。
* ワイルドカードを使用して現在のディレクトリ内の複数のファイルを検索する方法は、Customers.txtファイルのこの例に示されています。

次の「grep」コマンドは、「split」という単語を含む現在のディレクトリのファイルを再帰的に検索します。
‘split’という単語を含む現在のディレクトリとサブディレクトリのファイルは、次の行で出力されます。

$ grep -w split *
$ 

ディレクトリを再帰的に検索する

‘-r’ オプションは、「grep」コマンドとともに使用して、ディレクトリ内の特定の文字列またはパターンを再帰的に検索します。
この例では、「grep」コマンドを使用して現在のディレクトリを再帰的に検索し、Customers.txtファイルを検索します。

$ grep -wr split *
$ 
ヒント
ディレクトリを指定して再帰的に検索したい場合は、
$ grep 検索文字列 検索したい場所
となります。
$ grep -wr kpasswd /etc/services
kpasswd         464/udp     # kpasswd
kpasswd         464/tcp     # kpasswd
rpasswd	        774/tcp #
$

行番号を出力に追加します

「grep」コマンドの ‘-n’ オプションは、ファイルの行番号とともに検索文字列の出力を出力するために使用されます。
この例では、'-n’ オプションを指定した「grep」コマンドを使用して、最初の例で作成されたCustomers.txtファイルの行番号を含む検索出力を表示しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -n "Ali"
4:45  Minhaz Ali      ali@gmail.com       +8801190761212
$
ヒント
ターミナルから前のコマンドを実行すると、次の出力が表示されます。文字列「Riya」はファイルの3行目にあります。4行目と5行目は、一致する行の次の2行です。したがって、3行目、4行目、および5行目は、一致する文字列を強調表示することによって出力に出力されています。

一致する行の後に特定の行数を印刷します

数値を含む ‘-A’ オプションは、ファイル内で見つかった一致する文字列またはパターンの後に特定の行数を出力するために使用されます。
この例では、Customers.txtファイルに対して「grep」コマンドの ‘-A’ オプションを使用しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -A2 "Ali"
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
ヒント
ターミナルから前のコマンドを実行すると、次の出力が表示されます。文字列「Riya」はファイルの3行目にあります。4行目と5行目は、一致する行の次の2行です。したがって、3行目、4行目、および5行目は、一致する文字列を強調表示することによって出力に出力されています。

一致する行の前に特定の行数を印刷します

数値を含む ‘-B’ オプションは、ファイル内で一致する文字列またはパターンの前に特定の行数を出力するために使用されます。
この例では、Customers.txtファイルに対して「grep」コマンドの ‘-B’ オプションの使用法を示しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -B1 "Riya"
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
$
ヒント
文字列「Riya」はファイルの3行目にあります。2行目は、一致する行の前の行です。したがって、2行目と3行目は、一致する文字列を強調表示することによって出力に出力されています。

一致する行の前後の特定の行数を印刷します

数値を指定した ‘-C’ オプションは、ファイル内で見つかった一致する文字列またはパターンの前後の特定の行数を出力するために使用されます。
この例では、 Customers.txtファイルの「grep」コマンドの ‘-C’ オプションの使用法を示しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -C1 "Maliha"
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
ヒント
ターミナルから前のコマンドを実行すると、次の出力が表示されます。5行目には、文字列 ‘Maliha’が含まれています。4行目は一致する行の前の行で、6行目は一致する行の次の行です。したがって、4行目、5行目、および6行目は、一致する文字列を強調表示することによって出力に出力されています。

ブラケットを使用して特定の数字を一致させる[]

特定の桁の範囲は、角かっこ[]を使用して、「grep」コマンドの正規表現パターンで定義できます。
この例では、Customers.txtファイルの「grep」コマンドを使用して特定の数字を検索する方法を示します。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$ cat Customers.txt | grep '[3-5]'
$
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
$
ヒント
[3-5] は、3,4,5 のいずれかを検索文字列とするという意味となります。
2,3,4,5,6 としたい場合は、 [2-6]となります。

3番目のブラケットを使用してパターンを特定の文字と一致させる[]

ファイルの特定の文字は、角かっこ[]を使用してさまざまな方法で一致させることができます。
角かっこを使用してファイルから特定の行を検索することにより、正規表現パターンで文字の範囲または特定の文字を使用できます。
この例では、文字範囲または特定の文字のパターンを使用して、Customers.txtファイル内の特定の文字を検索する方法を示します。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep 'Ma[lr]'
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
ヒント
Ma から始まる単語を検索し、さらに続く文字列が ‘[lr]’ すなわち、l または r である文字列を検索します。いわゆる「Mal」と「Mar」を検索するという意味になります。

[:alnum:]クラスを使用してアルファベットと数字を一致させる

[:alnum:]クラスは、アルファベットと数字を照合するために正規表現パターンで使用されます。
パターン[A-z0-9]に相当します。

[:alpha:]クラスを使用してアルファベット文字を照合する

[:alpha:]クラスは、アルファベット文字のみに一致する正規表現パターンで使用されます。
パターン[A-z]に相当します。

[:digit:]クラスを使用して数字を照合する

[:digit:]クラスは、正規表現パターンで数字のみに一致するために使用されます。
パターン[0-9]と同等です。

[:lower:]クラスを使用して小文字を照合する

[:lower:]クラスは、すべての小文字のみに一致するように正規表現パターンで使用されます。
パターン[a-z]と同等です。

[:space:]クラスを使用してスペース文字を一致させる

[:space:]クラスは、スペース文字を含む行と一致させるために正規表現パターンで使用されます。

ヒント
tab文字、空白も含めて検索対象となります。
$ grep “test(タブ文字)” /path/to/file
:と、入力したい場合は、ctrl-v を入力してからタブを打つと入力される。

‘[[:space:]]’ では空白文字もタブ文字もマッチする。

これならメモなどからコピペできる。
$ grep “test[[:space:]]” /path/to/file

また、
$ grep test$'\t’ /path/to/file
であればタブだけがマッチする。

行頭からの検索

キャレット(^)記号は、ファイル内の特定の文字または文字列で始まる行と一致するように正規表現で使用されます。
この記号の使用法は、前に作成されたCustomers.txtファイルのこの例で示されています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep ^4
45  Minhaz Ali      ali@gmail.com       +8801190761212
$

ヒント
ターミナルから前のコマンドを実行すると、次の出力が表示されます。出力によると、customers.txtファイルには「 4 」で始まる行が1行だけ存在します。これは、出力に出力されたファイルの4行目です。

行の終わりに一致する

ドル($)記号は、ファイル内の特定の文字または文字列と行末を一致させるために正規表現で使用されます。
この記号の使用法は、前に作成されたCustomers.txtファイルのこの例で示されています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep 1212$
45  Minhaz Ali      ali@gmail.com       +8801190761212
$
ヒント
customers.txtファイルには「1212」で終わる行が1行だけ存在します。これは、出力に出力されたファイルの4行目です。

連結との一致

正規表現パターンは、複数のパターンを連結することで作成できます。
ドット(.)は、パターンを連結するために使用されます。
この例では、 Customers.txtファイルに対して「grep」コマンドと連結して使用する方法を示しています。

$ cat Customers.txt
ID  Name            Email           Phone
11  Md. Abir        abir@gmail.com      +8801813462458
23  Riya Chakroborti    riya@gmail.com      +8801937864534
45  Minhaz Ali      ali@gmail.com       +8801190761212
56  Maliha Chowdhury    maliha@gmail.com        +8801820001980
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
$ cat Customers.txt | grep -e '[MR]\.\*[Kk]'
23  Riya Chakroborti    riya@gmail.com      +8801937864534
79  Maruf Sarkar        maruf@gmail.com     +8801670908966
$
ヒント
customers.txtファイルには「R」と「M 」で始まり「 k 」で終わる2行が存在します。したがって、ファイルの3行目と6行目が出力に出力されています。

書籍の紹介

e-Stat hampelで時系列データの異常値検知

e-Stat hampelで時系列データの異常値検知

e-Stat でGoogle Custom Search APIを使おう(4)

e-Stat でGoogle Custom Search APIを使おう(4)