Linuxコマンド辞典 grep・egrep・fgrep・rgrepコマンド(テキスト処理)

指定したパターンにマッチした行を表示する「grep」コマンドの概要と使い方を記載しています。

RHEL Fedora CentOS Vine Deblan Ubuntu Plamo

参考サイト:Man page of INSTALL

概要・使用方法

指定された文字列パターンと一致する文字列があるかどうか調べます。指定したファイル、もしくは標準入力からの入力を読み込みこんで、パターンにマッチした行をすべて出力します。パターンは文字列、もしくは文字列の集合を表現する正規表現により、マッチングを行っています。grepは、単独で実行されることもありますが、パイプやリダイレクトと組み合わせてフィルタの役割として使われることが多いです。ファイルは、「*(アスタリスク)」を用いることですべて検索対象とすることができます。

また、grepの仲間として、egrep、fgrep、rgrepがありますが、それぞれ以下のように置き換えることができます。

  • egrep > grep -E
  • fgrep > grep -F
  • rgrep > grep -r

パターンは、正規表現を用いるため文字列を指定する場合、そのままでは特別な意味を持ってしまうため、シングルクォーテーション、ダブルクォーテーションで囲うようにしたほうが良いでしょう。

圧縮されているファイルを検索する場合は、zegrep及びzgrepを使用すると良いでしょう。zgrep は、compress や gzip で圧縮されたファイルに対して grep を呼び出します。

書式

$grep [オプション] "[パターン]" [ファイル名・・・]

オプション

-E
–extended-regrexp
拡張正規表現を利用する
-F
–fixed-strings
正規表現ではなく、固定文字列を高速に検索する
-P
–perl-regexp
パターンをPerlの正規表現として読み込む
-A 行数
–after-context=行数
パターンにマッチした行の後ろ、指定行数分を出力する
-B 行数
–before-context=行数
パターンにマッチした行の前、指定行数分を出力する
-C [行数]
-[行数]、–context=[行数]
パターンにマッチした前後の数行を出力する(デフォルトは2行)
-e パターン
–regexp=パターン
パターンを指定して検索する。複数パターンを行う場合、「-」を含む文字列を検索する場合に有効となる。
-f ファイル名
–file=ファイル名
指定したファイルからパターンを読み取る
-c
–count
マッチした行数だけ出力する。-vオプションと併せて利用すると、マッチしない行数を出力する
–color、–colour出力を色づける(色は環境変数GREP_COLORに依存する)
-H
–with-filename
1つのファイルを対象とした場合でも行頭にファイル名を出力する
-h
–no-filename
複数ファイルを対象とした場合、行頭へのファイル名の出力を行わない
–label=文字列指定した文字列をファイル名として行頭に挿入する。
標準入力から対象を入力した場合のファイル名として指定する。
-l
–files-with-matches
パターンにマッチするファイル名を出力する
-L
–files-without-matches
パターンにマッチしないファイル名を出力する
-i
–ignore-case
パターンの大文字と小文字を区別しない
-w
–word-regexp
パターンを完全な単語として検索する
(例えば、ばbyteを指定した場合はbyteは検出するが、Mbyteは検出しない)
-x
–line-regexp
パターンを完全な行として検索する
-n
–line-number
出力の行頭に入力ファイルでの行番号を表示する
-m 行数
–max-count=行数
指定した行数がマッチしたところで読み込みを止める
-o
–only-matching
パターンに合致する文字列のみ出力する
-R、-r
–recursive
ディレクトリの下も再帰的に読み込む
-v
–invert-match
パターンにマッチしない行を出力する
–exclude=パターン指定したパターンにマッチするものは読み込まない
–exclude-file=ファイル名ファイルに記述されたパターンにマッチするファイルは読み込まない
–exclude-dir=ディレクトリ名指定したディレクトリを検索対象にしない

ファイルから指定したパターンに合致する行を抜き出す

パスワードファイル内に「sunarin」が含まれている行を抽出しています。

$grep [パターン] [ファイル名]

実行結果

[sunarin@localhost work]$ grep sunarin /etc/passwd 
sunarin:x:1000:1000:sunarin:/home/sunarin:/bin/bash
[sunarin@localhost work]$ 

複数の検索候補にマッチする行を表示する

パスワードファイル内の「sunarin」と「root」パターンに合致する行を抽出しています。「|(パイプ)」は「\」でエスケープする必要があります。

$grep [パターン \| パターン] [ファイル名]

-Eオプションを使用することで、エスケープを省略することができます。

$grep -E [パターン \| パターン] [ファイル名]

実行結果

[sunarin@localhost work]$ grep "sunarin\|root" /etc/passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
sunarin:x:1000:1000:sunarin:/home/sunarin:/bin/bash
[sunarin@localhost work]$ 

「#」から始めるコメント行と空行を除去して表示する

「^パターン」は、特定の文字で始まる文字列が含まれる行を表示します。「パターン$」は特定の文字で終わる文字列を含む行を表示します。

また、-vオプションを使用することで、特定の文字列が含まれていない行を検索することができます。ここでは、特定の文字列を指定しないので空行が対象となります。

$grep -v -e ^# -e ^$ 

実行結果

catコマンドで表示すると以下のようにコメントと空行すべて表示されます。

[root@localhost ~]# cat /etc/ssh/sshd_config 
#       $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

コメントと空行が除去され現在設定が有効になっている行のみ表示することができます。

[root@localhost ~]# grep -v -e ^# -e ^$  /etc/ssh/sshd_config 
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile      .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem       sftp    /usr/libexec/openssh/sftp-server

特定のファイルを検索対象から外す

$grep --exclude=sample.txt -i 

実行結果

iplist.txtからipアドレスを検索するのを除外しhostlistからIPアドレスを検索しています。

[sunarin@localhost work]$ cat iplist.txt 

192.168.0.10
192.168.0.11
192.168.0.30
192.168.0.31
[sunarin@localhost work]$ grep --exclude=iplist.txt -i 192.168.0.10 *
hostlist1.txt:hostA 192.168.0.10
[sunarin@localhost work]$ 

テキストファイルから大文字と小文字を区別せず検索する

オプション「-i」を使用します。

$grep --exclude=sample.txt -i 

実行結果

[sunarin@localhost work]$ cat Country.txt 
1.Benin
2.Bhutan
3.Chile
4.Cyprus
5.benin
6.bhutan
[sunarin@localhost work]$ grep -i "bhutan" * <大文字・小文字を区別しません。
Country.txt:2.Bhutan
Country.txt:6.bhutan
[sunarin@localhost work]$ 
[sunarin@localhost work]$ grep "bhutan" * <大文字・小文字を区別します。
Country.txt:6.bhutan

特定の文字列が含まれている行を行番号を含めて表示する

$grep -n [パターン] [ファイル]

実行結果

[sunarin@localhost work]$ grep -n "bhutan" *
Country.txt:6:6.bhutan

特定の文字が含まれている行数を表示する

シェルスクリプトなどで、特定のパターンが含まれている行数(カウント)を使用して、処理を行うときなどに使用したりします。

$grep -c [パターン] [ファイル]

実行結果

ここでは、ホストリストに172.16から始まるIPアドレスがどれくらい存在するかカウントしています。

[sunarin@localhost work]$ cat hostlist1.txt 


hostA 192.168.0.10
hostB 192.168.0.11
hostC 172.16.0.20
hostD 172.16.0.21
hostE 172.16.0.22
[sunarin@localhost work]$ grep -c "172.16." hostlist1.txt 
3
[sunarin@localhost work]$ 

完全一致する単語を検索する

grepコマンドは、基本的には文字列に含まれる行を抽出しますが、完全に一致する単語だけを絞り込みたい場合があります。その場合は、-wオプションと-xオプションを付けてgrepコマンドを実行します。

完全な単語として一致する場合、抽出します。

$grep -w [パターン] [ファイル]

実行結果

[sunarin@localhost work]$ cat sample.txt 
abc
def
hij
100 kbyte sample.txt
5 byte boot.ini
[sunarin@localhost work]$ grep -w byte sample.txt 
5 byte boot.ini
[sunarin@localhost work]$ 

完全な行として一致する場合、抽出します。

$grep -x [パターン] [ファイル]
[sunarin@localhost work]$ cat sample.txt 
abc
def
hij
100 kbyte sample.txt
5 byte boot.ini
[sunarin@localhost work]$ grep -x def sample.txt 
def
[sunarin@localhost work]$ 

検索結果をさらに絞り込む方法

特定の条件で検索を行った結果に対して、さらに絞り込みを行いたい場合があると思います。その場合は、grepに対してさらに|(パイプ)でgrepを付け加え絞り込みます。

$grep [オプション] [パターン] [ファイル] | grep [オプション] [パターン]

実行結果

ここでは、172.16のIPアドレスから始まるホストを抽出し、さらにfloorAに属するIPアドレスを抽出しています。

[sunarin@localhost work]$ grep '172.16.' hostlist1.txt 
hostC floorA 172.16.0.20
hostD floorB 172.16.0.21
hostE floorA 172.16.0.22
[sunarin@localhost work]$ grep '172.16.' hostlist1.txt |grep 'floorA'
hostC floorA 172.16.0.20
hostE floorA 172.16.0.22
[sunarin@localhost work]$ 

ディレクトリ内を再帰的に特定の文字列が含まれているファイルを検索する

特定ディレクトリ以下の階層にあるファイルに対して検索を行うためには、-rオプションを付けてgrepコマンドを実行します。また、1行に多くの文字列が含まれて見づらくなる場合は、オプション-lを追加して、指定パターンが含まれるファイル名だけを表示すると良いでしょう。

$grep -r [パターン] [ファイル]
$grep -R [パターン] [ファイル]
$grep -lR [パターン] [ファイル]

実行結果

ここでは、sunarinが含まれているログをlogディレクトリ以下のすべてのファイルを再帰的に検索しています。

[sunarin@localhost work]$ tree log/
log/
├── 20220401
│   └── 20220401.log
└── 20220402
    └── 20220402.log

2 directories, 2 files
[sunarin@localhost work]$ grep -R 'sunarin'
log/20220401/20220401.log:20220401 06:00:00 sunarin login!
log/20220401/20220401.log:20220401 06:30:00 sunarin logout!
[sunarin@localhost work]$ 

特定の文字列が含まれていないファイルを検索する

特定の文字列が含まれていないファイルを検索するには、オプションの-Lを使用します。

$grep -RL [パターン] [ファイル]
$grep -rL [パターン] [ファイル]

実行結果

[sunarin@localhost work]$ tree log
log
├── 20220401
│   └── 20220401.log
└── 20220402
    └── 20220402.log

2 directories, 2 files
[sunarin@localhost work]$ grep -RL 'sunarin' log
log/20220402/20220402.log
[sunarin@localhost work]$