Linuxコマンド - grep
概要
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
コマンドで対象となるテキストファイルの総行数を取得して、その値を指定するとよい。
(取得する行間の行数が総行数を超えることがないため)
また、対象となるデータに範囲指定に使用する文字列が複数行含まれている場合は対応できない。