Ubuntuでファイルの内容を検索したい場合等に使用する「grep」(Global Regular Expression Print)コマンドの使い方を説明します。
色々な検索方法があるのですが、今回は入門編として基礎的な使用方法にしぼって記述しています。
grepの使い方入門
grepの基本的な使い方は下記のとおりです。
grep 検索条件 検索対象ファイル
下記は「grep」で「443」という文字を検索条件として「/etc/services」ファイルを検索しています。
$ grep 443 /etc/services https 443/tcp # http protocol over TLS/SSL https 443/udp # HTTP/3
検索対象ファイルは複数指定もできます
検索対象となるファイルは複数指定することも出来て、「*」(ワイルドカード)による指定も可能です。
下記は「*.txt」と指定しているので、拡張子が「.txt」のファイル全てが検索対象となります。
$ grep 03 ./*.txt ./num_01.txt:number_03 ./test_03.txt:This is test_03.txt ./test_all.txt:This is test_03.txt
検索結果の1行目を見ると、「num_01.txt」の「number_03」という部分が検索にヒットしたことがわかります。
コマンドの実行結果をgrep
コマンドの実行結果を「|」(パイプ)で「grep」に渡してあげると、検索条件にマッチしたものだけ表示するということも出来ます。
コマンド | grep 検索条件
実行例として「lsof -i」コマンドの実行結果から、「nginx」を「grep」で検索して表示させてみます。
$ sudo lsof -i | grep nginx nginx 846 root 6u IPv4 7818 0t0 TCP *:http (LISTEN) nginx 847 nginx 6u IPv4 7818 0t0 TCP *:http (LISTEN) nginx 848 nginx 6u IPv4 7818 0t0 TCP *:http (LISTEN)
ちなみに「lsof -i」は、現在使用しているネットワークのポートを表示するコマンドとなります。
オプション
「grep」には多くのオプションがありますが、今回は私が普段良く使用するオプションについて説明します。
- -n 検索結果に番号を表示
- -i 大文字と小文字を区別しない
- -r ディレクトリ内も検索
- -v 検索条件にマッチしなかったものを表示
- -A3 検索結果に一致した行の3行後まで表示(数字部分は任意)
- -B3 検索結果に一致した行の3行前まで表示(数字部分は任意)
- -C3 検索結果に一致した行の3行前後まで表示(数字部分は任意)
-n 検索結果に番号を表示
「-n」オプションを使用すると、検索にヒットした部分の行番号も最初に含めて表示してくれます。
下記の例では「443」を検索条件としていますが、「/etc/services」の83と84行目が検索にヒットしていることが表示されています。
$ grep -n 443 /etc/services 83:https 443/tcp # http protocol over TLS/SSL 84:https 443/udp # HTTP/3
-i 大文字と小文字を区別しない
「-i」オプションを使用すると、大文字と小文字を区別せず検索を行います。
検証用に下記のようなテキストファイルを用意しました。
$ cat apple.txt Apple apple
「-i」オプションを使用しない場合
「-i」オプションを使用せずに検索条件を「Apple」とすると、「Apple」だけが検索にヒットします。
$ grep Apple apple.txt Apple
「-i」オプションを使用した場合
「-i」オプションを使用すると、大文字小文字を区別しなくなるので「Apple」と「apple」の両方が検索にヒットするようになります。
$ grep -i Apple apple.txt Apple apple
検索条件を全て大文字にしても「Apple」と「apple」の両方が検索にヒットします。
$ grep -i APPLE apple.txt Apple apple
-r ディレクトリ内も検索
「-r」オプションを使用すると、検索対象にディレクトリが含まれていた場合その中にあるファイルも出検索対照して検索を行ってくれます。
「-r」オプションの動作検証のために、下記のように「./apple.txt」と「./sub_dir/fruit.txt」を用意しました。
$ ls -lR ./ ./: total 8 -rw-rw-r-- 1 tamohiko tamohiko 12 Dec 22 22:17 apple.txt drwxrwxr-x 2 tamohiko tamohiko 4096 Dec 23 16:18 sub_dir ./sub_dir: total 4 -rw-rw-r-- 1 tamohiko tamohiko 18 Dec 22 22:29 fruit.txt
「-r」オプションを使用しない場合
「-r」オプションを使用しない場合は、検索対象にディレクトリが含まれているとディレクトリであるとのメッセージが表示されて、ディレクトリ内のファイルは検索対象とされません。
下記の例では検索対象を「./*」としているので、カレントディレクトリ内の全てを検索対象としていますが、「sub_dir」はディレクトリであるとメッセージを表示して、その中のファイルについては検索対象とはしていません。
$ grep Apple ./* ./apple.txt:Apple grep: ./sub_dir: Is a directory
「-r」オプションを使用した場合
「-r」オプションを使用すると、ディレクトリの中にあるファイルも検索対象にしてくれるので、下記のように「sub_dir」ディレクトリにあるファイルも検索対象としてくれています。
$ grep -r Apple ./* ./apple.txt:Apple ./sub_dir/fruit.txt:Apple
-v 検索条件にマッチしなかったものを表示
「-v」オプションを使用すると、検索条件にマッチしなかったものが表示されます。
「-v」オプションの動作検証のために、下記のファイルを用意しました。
$ cat fruit.txt Apple Orange Pine
「-v」オプションを使用して「Apple」を検索すると、検索条件にマッチしなかった方が表示されます。
$ grep -v Apple fruit.txt Orange Pine
-A 3 検索結果に一致した行の3行後まで表示(数字部分は任意)
「-A 数字」オプションを使用すると、検索条件にヒットした行より指定した数字の分だけ後の行も一緒に表示します。
下記の例では「-A 3」と指定しているので、3行分後の行も一緒に表示されています。
$ grep -n -A 3 110 /etc/services 44:pop3 110/tcp pop-3 # POP version 3 45-sunrpc 111/tcp portmapper # RPC 4.0 portmapper 46-sunrpc 111/udp portmapper 47-auth 113/tcp authentication tap ident
-B 3 検索結果に一致した行の3行前まで表示(数字部分は任意)
「-B 数字」オプションを使用すると、検索条件にヒットした行より指定した数字の分だけ前の行も一緒に表示します。
下記の例では「-B 3」と指定しているので、3行分前の行も一緒に表示されています。
$ grep -n -B 3 110 /etc/services 41-kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5 42-iso-tsap 102/tcp tsap # part of ISODE 43-acr-nema 104/tcp dicom # Digital Imag. & Comm. 300 44:pop3 110/tcp pop-3 # POP version 3
-Aと-Bは組み合わせ可能
「-A 数字」と「-B 数字」オプションは、組み合わせて一緒に表示する行数を指定することが出来ます。
下記の例では「-A 3」「-B 5」と指定して、前の5行と後の3行をあわせて表示しています。
$ grep -A 3 -B 5 -n 110 /etc/services 39-http 80/tcp www # WorldWideWeb HTTP 40-kerberos 88/tcp kerberos5 krb5 kerberos-sec # Kerberos v5 41-kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5 42-iso-tsap 102/tcp tsap # part of ISODE 43-acr-nema 104/tcp dicom # Digital Imag. & Comm. 300 44:pop3 110/tcp pop-3 # POP version 3 45-sunrpc 111/tcp portmapper # RPC 4.0 portmapper 46-sunrpc 111/udp portmapper 47-auth 113/tcp authentication tap ident
-C 3 検索結果に一致した行の3行前後まで表示(数字部分は任意)
「-C 数字」オプションを使用すると、検索条件にヒットした行より指定した数字の分だけ前と後の行も一緒に表示します。
下記の例では「-C 3」と指定しているので、3行分前と後の行も一緒に表示されています。
$ grep -n -C 3 110 /etc/services 41-kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5 42-iso-tsap 102/tcp tsap # part of ISODE 43-acr-nema 104/tcp dicom # Digital Imag. & Comm. 300 44:pop3 110/tcp pop-3 # POP version 3 45-sunrpc 111/tcp portmapper # RPC 4.0 portmapper 46-sunrpc 111/udp portmapper 47-auth 113/tcp authentication tap ident
「-3」でも検索結果に一致した行の3行前後まで表示します(数字部分は任意)
前後の行を表示する場合、「-数字」と指定することで、検索条件にヒットした行より指定した数字の分だけ前と後の行も一緒に表示することができます。
下記の例では「-3」と指定しているので、3行分前と後の行も一緒に表示されています。
$ grep -n -3 110 /etc/services 41-kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5 42-iso-tsap 102/tcp tsap # part of ISODE 43-acr-nema 104/tcp dicom # Digital Imag. & Comm. 300 44:pop3 110/tcp pop-3 # POP version 3 45-sunrpc 111/tcp portmapper # RPC 4.0 portmapper 46-sunrpc 111/udp portmapper 47-auth 113/tcp authentication tap ident
正規表現(メタ文字)
「grep」で使用できる正規表現のメタ文字について簡単に説明します。
メタ文字 | 意味 | 例 |
---|---|---|
^ | 行頭 | ^abcは行の最初がabcにマッチ |
$ | 行末 | abc$は行の最後がabcにマッチ |
. | 任意の一文字 | a.cはabc aac a!c a1c等にマッチ |
* | 直前の文字の0回以上の繰り返し (ワイルドカードではないので注意) |
ab*cはac abc abbbc等にマッチ |
[文字] | []内のどれかの文字 | [abc]はa,b,cのどれかにマッチ [a-c]のような範囲指定も可 |
[^文字] | [^]内の文字以外 | [^abc]はa,b,c以外にマッチ [^a-c]のような範囲指定も可 |
\ | メタ文字の打ち消し |
grepで正規表現を使う場合は「'検索条件'」シングルクォーテーションで囲もう
正規表現を使用する場合は「'」シングルクォーテーションで検索条件を囲みましょう。
シングルクォーテーションで括らない場合は、メタ文字をシェルとして展開しようとするので、意図しない動作をしてしまうことがあります。
動作例
検証用に「grep_01.txt」という下記内容のファイルを用意しました。
$ cat grep_01.txt abcde ab ab c abbcde ab bcd aabccd acb de
シングルクォーテーションで囲まない場合
検索条件をシングルクォーテーションで囲まないで、「b .」(bの後ろに空白その後に任意の文字)として「grep」で検索してみます。
$ grep b . grep_01.txt grep: .: Is a directory grep_01.txt:abcde grep_01.txt:ab grep_01.txt:ab c grep_01.txt:abbcde grep_01.txt:ab bcd grep_01.txt:aabccd grep_01.txt:acb de
シェルが「.」をカレントディレクトリとして解釈したものを「grep」に渡してしまっているため、検索条件が「b」検索対象が「.」(カレントディレクトリ)と「grep_01.txt」となってしまっています。
そのため検索結果が意図したものと異なってしまいました。
シングルクォーテーションで囲んだ場合
検索条件「b .」をシングルクォーテーションで囲んで「grep」で検索を行ってみます。
$ grep 'b .' grep_01.txt ab c ab bcd acb de
この場合、「b .」(bの後ろに空白その後に任意の文字)が検索条件として「grep」に渡されているため意図したとおりの検索結果が表示されています。
コメント