Linuxコマンド - grep

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

grepコマンドとは、ファイル中の文字列に対して、正規表現を使って検索して表示するコマンドである。
ここでは、grepの基本操作を記載する。


grepのインストール

多くのLinuxディストリビューションでは、標準でgrepがインストールされている。
もし、別途インストールする必要がある場合、ソースコードからgrepをインストールする。

まず、grepのビルドに必要なライブラリをインストールする。

# RHEL
sudo dnf install make gcc gcc-c++ glibc-devel pcre2-devel

# SUSE
sudo zypper install make gcc gcc-c++ glibc-devel pcre2-devel


GNUソフトウェアの公式Webサイトにアクセスして、ソースコードをダウンロードする。
ダウンロードしたファイルを解凍する。

tar xf grep-<バージョン>.tar.xz
cd grep-<バージョン>


grepをビルドおよびインストールする。

mkdir build && cd build

../configure --prefix=<grepのインストールディレクトリ>
make -j $(nproc)
make install


~/.profileファイル等に、環境変数PATHを追記する。

vi ~/.profile


 # ~/.profileファイル
 
 export PATH="/<grepのインストールディレクトリ>/bin:$PATH"



grepコマンドの基本

grepコマンドの基本動作

grepコマンドは、ファイル中の文字列を検索するコマンドである。
使用方法は、次に示す通り、シンプルなものになっている。

grep <検索正規表現> <ファイル名>


以下の例では、testディレクトリに存在する全てのファイルから、hogeという文字列を検索している。
-nオプションを付加することで、マッチしたファイルの行番号も表示する。
-rオプションを付加することで、サブディレクトリに存在するファイルも再帰検索する。

grep "hoge" -nr test/*


grepコマンドのand検索

grepコマンドでは、2つ以上の条件を設定して検索するand検索ができる。
基本的には、パイプで繋げて記述する。

grep <検索文字列> <ファイル名> | grep <検索文字列2>


1文の中でのand検索では、次のように正規表現を使う。
.は任意の文字、*は直前の文字の0個以上の繰り返しを表す正規表現である。

grep <スタートの検索文字列.*終わりの検索文字列> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、rで始まりpで終わる文字列が存在する行を検索するには、以下のようにする。

grep r.*p work/*



grepコマンドのオプション

-iオプション : 大文字と小文字を区別せず検索する

grepコマンドに-iオプションをつけると、大文字と小文字を区別せずに検索できる。

grep –i 検索正規表現 ファイル名


例えば、testディレクトリ内の全てのファイルから大文字のAと小文字のaが区別なく検索するには、以下のようにする。

grep –i a test/*


-Eオプション : 拡張正規表現で検索を行う

2つの条件のOR検索を行うには、|のOR演算子を使用するが、そのためには拡張正規表現を使う必要がある。
その拡張席表現をするものが、-Eオプションである。

grep –E <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、小文字のpまたはeのいずれかを検索するには、以下のようにする。

grep –E 'p|e' test/*


grepコマンドは、多くの正規表現を使用することができる。
ただし、grepコマンドの正規表現の記述方法は、他のプログラム言語の正規表現はやや異なっているので注意する。

下表に、grepコマンドで使用できる正規表現を示す。
併せて、sedコマンドとawkコマンドの正規表現も記載する。

grep sed awk 意味
. . . 任意の1文字
* * * 直前の1文字または1パターンの0回以上の繰り返し
^ ^ ^ 行の先頭
$ $ $ 行の末尾
\( \) \( \) () パターンのグループ化
\1 \2 \3 \1 \2 \3 後方参照
[ ] [ ] [ ] 括弧内の任意の1文字
\{n\} \{n\} {n} 直前の1文字または1パターンのn回の繰り返し
\{n, \} \{n, \} {n, } 直前の1文字または1パターンのn回以上の繰り返し
\{n, m\} \{n, m\} {n, m} 直前の1文字または1パターンのn回以上かつm回以下の繰り返し
\+ \+ + 直前の1文字あるいは1パターンの1回以上の繰り返し
\? ? 直前の1文字あるいは1パターンの0回または1回だけ出現
\| \| | 2 パターンのうちどちら片方


-eオプション : 一致処理に指定した正規表現

-eオプションは、一致処理に指定した正規表現を行うオプションであるが、実際には、OR検索を行う時に使用する。

grep –e <検索正規表現1> –e <検索正規表現2> <ファイル名>


例えば、-eオプションを使用して、testディレクトリ内の全てのファイルから、大文字のpまたはeのいずれかを検索するには、以下のようにする。

grep –e p –e e work/*


-vオプション : 一致しないものを検索する

-vオプションは、一致しないものを検索する時に使用する。

grep –v <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、1の文字を含まないものを検索するには、以下のようにする。

grep -v 1 test/*


-nオプション : 検索結果に行番号を表示する

-nオプションは、検索結果に行番号を表示する。

grep –n <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、aを検索して結果を行番号と合わせて表示するには、以下のようにする。

grep -n a test/*


-lオプション : 検索結果にファイル名のみ表示する

-lオプションは、検索した結果にファイル名のみを表示したい時に使用する。

grep –l <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、aの文字を検索してファイル名を表示するには、以下のようにする。

grep -l a test/*


-hオプション : 検索結果にファイル名を表示しない

-hオプションは、検索した結果にファイル名を表示しない時に使用する。

grep –h <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、hの文字を検索してファイル名は表示しない場合は、以下のようにする。

grep -h a test/*


また、ファイル名を表示せずに行番号と該当内容のみ表示する場合は、-nオプションと-hオプションを組み合わせる。
例えば、testディレクトリ内の全てのファイルから、aの文字を検索して行番号とファイル名の表示をするには、以下のようにする。

grep -nh a test/*


-oオプション : 検索結果に一致した文字を表示する

-oオプションは、検索した時に該当したファイルを表示する。

grep –o <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、pで始まりeで終わる文字を検索して、該当の文字とともに表示する場合は、以下のようにする。

grep -o p.*e test/*


-Cオプション : 検索結果に一致した箇所から前後に指定した行数を表示する

-Cオプションは、検索した結果に合わせて、前後に指定した行数を表示する。

grep –C <行数> <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、2の文字を検索して、あわせて、前後に行ずつ表示する場合は、以下のようにする。

grep -C 1 2 test/*


-rオプション : ディレクトリ内も検索対象とする

-rオプションは、ディレクトリ内を再帰検索する時に使用する。

grep –r <検索正規表現> <ファイル名>


例えば、testディレクトリ内にある下層のディレクトリも含めて全てのファイルから、aの文字を検索するには、以下のようにする。

grep -r a test/*


-Lオプション : 検索した結果、該当しなったファイルを表示する

-Lオプションは、検索した結果、該当しなったファイルを表示する。

grep –L <検索正規表現> <ファイル名>


例えば、testディレクトリ内の全てのファイルから、aを検索した結果、該当しなかったファイルを表示する場合は、以下のようにする。

grep -L a test/*



grepコマンドを使用したフィルタリング

特定の文字列を含む行のみを表示する

コマンドの出力結果や単一・複数のファイルから、特定の文字列を含む行を検索してその行を表示するには、grepコマンドを使用する。

grepコマンドは、指定した文字列を含む行を検索して、その文字列を含む行のみを表示する。
指定した文字列が見つからなかった場合は、何も表示しない。

grep <検索パターン>  # grepコマンドで特定の文字列を含む行のみを抽出する


以下の例では、テキストファイルから検索パターンを含む行を表示している。

cat test.txt

abc
def
ghi


grep 'i' test.txt

ghi


検索パターンが含まれる行が見つかった場合は、終了ステータスは0になる。

echo $?

0


以下の例では、検索パターンaまたはzを含む行を表示している。(正規表現)

grep '[az]' test.txt

abc


以下の例では、検索パターンfからlのいずれかの文字を含む行を表示している。(正規表現)
[]の中に-(ハイフン)で検索する文字の範囲を指定する。

grep '[f-l]' test.txt

def
ghi


以下の例では、行全体が特定のパターンと一致する行を表示している。(正規表現)

grep '^abc$' test.txt

abc


また、パターンと行全体が完全一致する行の検索は、-xオプションを指定することでも可能である。

grep -x 'abc' test.txt

abc


以下の例では、OR条件を使用した検索を行っている。(正規表現)
-Eオプションを指定することで拡張正規表現が使用できるようになる。
正規表現を使用する場合は、常に、-Eオプションを指定するようにしたほうがよい。

grep -E 'a|z' test.txt

abc


grep -E 'a|m|z' test.txt

abc


以下の例では、複数のファイルを対象とした検索を行っている。
検索対象となるテキストファイルは、以下の2つ(test1.txt、test2.txt)を使用する。

cat test1.txt

abc
def
ghi

cat test2.txt

ABC
DEF
GHI


以下の例では、複数のファイルからパターンを含む行を検索して表示している。
対象ファイルにワイルドカードを指定して、検索対象に複数ファイルを指定している。
この場合、単一ファイルからの検索とは異なり、結果表示に該当ファイル名が含まれる。

grep -i 'abc' test*

test1.txt:abc
test2.txt:ABC


また、引数に複数のファイルを指定することもできる。

grep -i 'abc' test1.txt test2.txt

test1.txt:abc
test2.txt:ABC


特定の文字列を含まない行のみを表示する

コマンドの出力結果または単一・複数のファイルから、特定の文字列を含まない行を検索してその行を表示するには、
grepコマンドの-vオプションを使用する。

grep -v <検索パターン>  # grepコマンドと-vオプションで特定の文字列を含まない行のみを抽出する


cat test.txt

abc
def
ghi


以下の例では、-vオプションに指定したaが含まれない行のみ表示している。

grep -v 'a' test.txt

def
ghi


行番号を付加して表示する

grepコマンドは、-nオプションを指定することにより、実行結果の先頭に行番号を付加して表示することができる。

grep -n <検索パターン>  # grepコマンドと-nオプションで検索結果に行番号を付加する


cat test.txt

abc
def
ghi


grep -n 'i' test.txt

3:ghi


検索せずに、テキストファイルに行番号を付加したい場合は、-nオプションを付加して検索パターンに(空文字)を指定する。
空文字で検索すると全ての行と一致するため、テキストファイルの全行に行番号が付加された状態で出力される。

grep -n  test.txt

1:abc
2:def
3:ghi


A行からB行までを切り出す

テキストファイル等から、<検索パターン1>を含む行から<検索パターン2>を含む行までを表示するには、
grepコマンドの-Aオプションと-Bオプションを組み合わせて使用する。

grep -A <行数1> '<検索パターン1>' <検索するファイル> | grep -B <行数2> '<検索パターン2>'  # grepコマンドの-Aオプションと-Bオプションで特定の2行の行間を表示する


  • -Aオプション
    指定した文字列と一致した行から下のn行を取得するオプションである。
  • -Bオプション
    -Aオプションとは逆に、指定した文字列と一致した行から上のn行を取得するオプションである。


以下の例では、-Aオプションで'hogehoge'の行から下の<行数1>までを切り出して、
-Bオプションで'fugafuga'を含む行から上の<行数2>までの'hogehoge'を含む行までを切り出している。

ただし、最下行までと最上行までを取得するためにオプションに1000000と指定しているため、
対象となるデータが1000000行を超えている場合は対応できない。
(1000000行を超えるテキストファイルを扱う機会は稀なので、ほぼ問題はない)

cat test.txt

abc
def
ghi
jkl
mno
pqr


grep -A 1000000 'i' test.txt | grep -B 1000000 'n'

ghi
jkl
mno


厳密な処理を行う場合、事前にwc -lコマンドで対象となるテキストファイルの総行数を取得して、その値を指定するとよい。
(取得する行間の行数が総行数を超えることがないため)

また、対象となるデータに範囲指定に使用する文字列が複数行含まれている場合は対応できない。