🧗

grepコマンドで文字列検索をする

2022/10/31に公開

どうもoreoです。

今回は文字列を検索するのに便利なgrepコマンドについて記載します。

1 概要

1-1 サンプルファイルについて

下記のようなディレクトリ構成とサンプルファイルで、grepコマンドの実験をしてみます!

├── files.txt
├── fruits.txt
└── laugh.txt
files.txt
test.js
tett.js
teut.js
tewt.js
text.js
teyt.js
tezt.js
    
example.css
example-css.scss
    
customer1.json
customer2.json
customer3.json
customer4.json
fruits.txt
banana
apple
watermelon
orange
BANANA
laugh.txt
ll.html
lol.html
lool.html
loool.html
lollol.html

1-2 基本的な使い方

grepは文字列が検索できるコマンドです。対象ファイル(または対象ディレクトリ)で、検索パターンに一致した文字列を含む行を出力することができます。

grep オプション 検索パターン 対象ファイル名()

(*)ファイルの複数指定や-rなどでディレクトリ指定も可能。

以下を実行するとbanが含まれる行が出力されます。

grep ban fruits.txt
出力結果
banana

対象のファイルなどを指定しなければ、検索対象を標準入力から読みこむことができます。例えば

lsコマンドと組み合わせると、ディレクトリ内のファイル検索ができます。

ls | grep files
出力結果
files.txt

1-2 オプションについて

grepコマンドには様々なオプションがあり、代表的なものを記載します。

-nオプション

検索バターンに一致した行番号と行を出力します。

grep -n ban fruits.txt
出力結果
1:banana

-iオプション

検索バターンに大文字と小文字を区別せずに一致した行を出力します。

grep -i  ban fruits.txt
出力結果
banana
BANANA

-vオプション

検索バターンに一致しなかった行を出力します。

grep -v  ban fruits.txt
出力結果
apple
watermelon
orange
BANANA

-cオプション

検索バターンに一致した行数を出力します。下記例では、lを含む行数を出力します。

grep -c l  fruits.txt
出力結果
2

1-3 正規表現(基本正規表現)

正規表現を利用すると様々な条件で検索することが可能です。''で正規表現を囲まなければ、シェルが正規表現を展開し、意図しない検索結果になる可能性がある為、基本的には''で囲んで使用します。

正規表現の中で、意味を持つ記号のことをメタ文字と言い、ここでは代表的なメタ文字を記載します。

先頭を表す^

grep '^example'  files.txt
出力結果
example.css
example-css.scss

行末を表す$

grep 'json$'  files.txt
出力結果
customer1.json
customer2.json
customer3.json
customer4.json

空行を表す^$

-nオプションと組み合わせると空行の行番号を出力できます

grep -n '^$'  files.txt
出力結果
8:
11:

-vと組み合わせると、空行を削除できます。

grep -v '^$'  files.txt
出力結果
test.js
tett.js
teut.js
tewt.js
text.js
teyt.js
tezt.js
example.css
example-css.scss
customer1.json
customer2.json
customer3.json
customer4.json

任意の一文字に一致する.

grep 'te.t'  files.txt
出力結果
test.js
tett.js
teut.js
tewt.js
text.js
teyt.js
tezt.js

.は、2つ続けて任意の2文字として検索可能です。

grep 't..t'  files.txt
出力結果
test.js
tett.js
teut.js
tewt.js
text.js
teyt.js
tezt.js

.そのもののを検索したい場合は、.の前に\をつけることで検索することが可能です。メタ文字の前に\をつけることでその意味を無効にすることが可能で、メタ文字の意味を打ち消すことをエスケープと言います

grep '\.css'  files.txt
出力結果
example.css

特定の文字を指定できる[]

下記のように[]を使用すると、testまたはtettに一致するものを検索できます。

grep 'te[st]t'  files.txt
出力結果
test.js
tett.js

括弧内ではハイフンでアルファベットや数字の範囲を指定できます

grep 'te[s-y]t'  files.txt
出力結果
test.js
tett.js
teut.js
tewt.js
text.js
teyt.js
grep 'mer[1-3]'  files.txt
出力結果
customer1.json
customer2.json
customer3.json

括弧内に^をつけると括弧内に記載した文字以外を検索することできます。以下は、testまたはtett以外に一致した場合を検索できます。

grep 'te[^st]t'  files.txt
出力結果
teut.js
tewt.js
text.js
teyt.js
tezt.js

直前の正規表現が0回以上の繰り返されていることを表す*

以下の例では、llの間でoが0回以上繰り返されている文字列を検索します。

grep 'lo*l' laugh.txt
出力結果
ll.html
lol.html
lool.html
loool.html
lollol.html

1-4 拡張正規表現

1-3で紹介した正規表現(基本正規表現)は、正規表現が使える全てのコマンドで使用することが可能です。拡張正規表現とは、基本正規表現を拡張したもので、grepでは、-Eオプションを使うと使用することができます。

ここでは、代表的な拡張正規表現のメタ文字を記載します。

直前の文字が1回以上繰り返されていることを表す+

以下の例では、llの間でoが1回以上繰り返されている文字列を検索します。

grep -E 'lo+l' laugh.txt
出力結果
lol.html
lool.html
loool.html
lollol.html

直前の文字が0回または1回の繰り返されていることを表す?

grep -E 'lo?l' laugh.txt
出力結果
ll.html
lol.html
lollol.html

直前の文字がm回以上n回以下繰り返されていることを表す{m,n}

grep -E 'lo{2,4}l' laugh.txt
出力結果
lool.html
loool.html

{m}だけを記載するとちょうどm回の繰り返しを検索できます。

grep -E 'lo{3}l' laugh.txt
出力結果
loool.html

{m,}だけを記載するとm回以上の繰り返しを検索できます。

grep -E 'lo{2,}l' laugh.txt
出力結果
lool.html
loool.html

正規表現をグループ化できる()

grep -E '(lol)+' laugh.txt
出力結果
lol.html
lollol.html

OR条件の|

grep -E 'll|lol' laugh.txt
出力結果
ll.html
lol.html
lollol.html

1-5 基本正規表現と拡張正規表現の対応

\を使用すると、拡張正規表現を基本正規表現で表すことができ、ここではその一部を記載します。

基本正規表現 拡張正規表現 意味
* * 0回以上の繰り返し
なし + 1回以上の繰り返し
なし ? 0回または1回の繰り返し
\{m,n\} {m,n} m回以上n回以下の繰り返し
\{m\} {m} ちょうどm回の繰り返し
\{m,\} {m,} m回以上の繰り返し
\(\) () グループ化
なし | 複数の正規表現をOR条件で連結

3 最後に

grepコマンドを使用すると、ログ調査や複雑な文字列検索に便利なので、ぜひマスターしたいですね!

4 参考

https://man7.org/linux/man-pages/man1/grep.1.html

https://tech-blog.rakus.co.jp/entry/20220912/grep

https://www.wakuwakubank.com/posts/337-linux-grep/

https://www.sbcr.jp/product/4797380941/

Discussion