ファイル(または一連のファイル)があり、これらのファイル内の特定の文字列または構成設定を検索するとします。各ファイルを個別に開いて特定の文字列を見つけようとするのは面倒で、おそらく適切なアプローチではありません。では、何を使用できるでしょうか?
*nixベースのシステムでテキストを検索および操作するために使用できるツールはたくさんあります。この記事では、grep
について説明します。 ファイル内にあるかストリームからのものかを問わず、パターンを検索するコマンド(ファイルまたはパイプからの入力コンピング、または|
)。今後の記事では、sed
の使用方法についても説明します。 (ストリームエディタ)ストリームを操作します。
プログラムまたはユーティリティの動作を理解する最良の方法は、そのマニュアルページを参照することです。多くの(すべてではないにしても)Unixツールは、インストール中にマニュアルページを提供します。 Red Hat Enterprise Linuxベースのシステムでは、以下を実行してgrep
を一覧表示できます。 のドキュメントファイル:
$ rpm -qd grep
/usr/share/doc/grep/AUTHORS
/usr/share/doc/grep/NEWS
/usr/share/doc/grep/README
/usr/share/doc/grep/THANKS
/usr/share/doc/grep/TODO
/usr/share/info/grep.info.gz
/usr/share/man/man1/egrep.1.gz
/usr/share/man/man1/fgrep.1.gz
マニュアルページを自由に使用できるので、grep
を使用できるようになりました。 そしてそのオプションを探ります。
grep
基本
記事のこの部分では、words
を使用します 次の場所にあるファイル:
$ ls -l /usr/share/dict/words
lrwxrwxrwx. 1 root root 11 Feb 3 2019 /usr/share/dict/words -> linux.words
このファイルには479,826語が含まれており、words
によって提供されます。 パッケージ。私のFedoraシステムでは、そのパッケージはwords-3.0-33.fc30.noarch
です。 。 words
の内容をリストするとき ファイルの場合、次の出力が表示されます:
$ cat /usr/share/dict/words
1080
10-point
10th
11-point
[……]
[……]
zyzzyva
zyzzyvas
ZZ
Zz
zZt
ZZZ
わかりました。words
ファイルには479,826行が含まれていましたが、どうすればそれを知ることができますか?覚えておいてください、私たちは以前にマニュアルページについて話しました。 grep
かどうか見てみましょう 特定のファイルの行をカウントするオプションを提供します。
皮肉なことに、grep
を使用します 次のようにオプションをgrepします:

したがって、明らかに-c
が必要です。 、または長いオプション--count
、特定のファイルの行数をカウントします。 /usr/share/dict/words
の行を数える 収量:
$ grep -c '.' /usr/share/dict/words
479826
'.'
少なくとも1つの文字、スペース、空白、タブなどを含むすべての行をカウントすることを意味します。
grep
正規表現
grep
正規表現(regexes)を使用すると、コマンドがより強力になります。したがって、grep
に焦点を当てながら コマンド自体については、基本的な正規表現の構文についても触れます。
Z
で始まる単語にのみ関心があると仮定しましょう。 。この状況では、正規表現が役立ちます。カラットを使用します(^
)文字列の先頭を示す特定の文字で始まるパターンを検索するには:

特定の文字で終わるパターンを検索するには、ドル記号($
)を使用します )文字列の終わりを示します。 hat
で終わる文字列を検索する以下の例を参照してください。 :

hat
を含むすべての行を印刷するには 行の先頭でも末尾でも、その位置に関係なく、次のようなものを使用します。

^
および$
メタ文字と呼ばれ、円記号(\
)でエスケープする必要があります )これらの文字を文字通り一致させたい場合。メタ文字について詳しく知りたい場合は、https://www.regular-expressions.info/characters.htmlを参照してください。
例:コメントを削除する
これで、grep
の表面をスクラッチしました 、実際のシナリオに取り組みましょう。 * nixの多くの構成ファイルには、構成ファイル内のさまざまな設定を説明するコメントが含まれています。 /etc/fstab
、たとえば、ファイルには次のものがあります:
$ cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Oct 27 05:06:06 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
#/dev/mapper/VGCRYPTO-SWAP swap swap defaults,x-systemd.device-timeout=0 0 0
コメントはハッシュ(#
)でマークされています )、印刷時に無視したい。 1つのオプションはcat
です コマンド:
$ cat /etc/fstab | grep -v '^#'
ただし、cat
は必要ありません ここで(猫の無用な使用を避けてください)。 grep
コマンドはファイルを完全に読み取ることができるため、代わりに次のようなものを使用して、コメントを含む行を無視できます。
$ grep -v '^#' /etc/fstab
代わりに、出力(コメントなし)を別のファイルに送信する場合は、次を使用します。
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
grep
画面上の出力をフォーマットできますが、このコマンドはその場でファイルを変更できません。これを行うには、ed
のようなファイルエディタが必要です 。次の記事では、sed
を使用します ここでgrep
を使用して行ったのと同じことを実現するため 。
例:コメントと空の行を削除する
まだgrep
を使用している間 、/etc/sudoers
を調べてみましょう ファイル。このファイルには多くのコメントが含まれていますが、コメントのない行にのみ関心があり、空の行も削除したいと考えています。
それでは、まず、コメントを含む行を削除しましょう。次の出力が生成されます:
# grep -v '^#' /etc/sudoers
Defaults !visiblepw
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
ここで、空白の(空の)行を削除します。それは簡単です。別のgrep
を実行するだけです。 コマンド:
# grep -v '^#' /etc/sudoers | grep -v '^$'
Defaults !visiblepw
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
valentin.local ALL=NOPASSWD: /usr/bin/updatedb
もっと上手くできますか? grep
を実行できますか grep
をフォークせずに、よりリソースに優しいコマンド 二度?確かに次のことができます:
# grep -Ev '^#|^$' /etc/sudoers
Defaults !visiblepw
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
valentin.local ALL=NOPASSWD: /usr/bin/updatedb
ここでは、別のgrep
を紹介しました オプション、-E
(または--extended-regexp
)<PATTERN>
は拡張正規表現です。
例:/etc/passwd
のみを印刷する ユーザー
grep
であることは明らかです 正規表現とともに使用すると強力です。この記事では、grep
のほんの一部を取り上げています。 本当に可能です。 grep
の機能をデモンストレーションする 正規表現を使用して、/etc/passwd
を解析します ユーザー名のみをファイルして印刷します。
/etc/passwd
の形式 ファイルは次のとおりです:
$ head /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
上記のフィールドの意味は次のとおりです。
<name>:<password>:<UID>:<GID>:<GECOS>:<directory>:<shell>
man 5 passwd
を参照してください /etc/passwd
の詳細については ファイル。ユーザー名のみを印刷するには、次のようなものを使用できます。
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
上記のgrep
コマンド、別のオプションを導入しました:-o
(または--only-matching
)<PATTERN>
に一致する行の一部のみを表示します 。次に、-Eo
を組み合わせました 目的の結果を得るには。
ここで、上記のコマンドを分割して、実際に何が起こっているのかをよりよく理解できるようにします。左から右へ:
-
^
行の先頭で一致します。 -
[a-zA-Z_-]
は文字クラスと呼ばれ、含まれるリストに一致する単一の文字と一致します。 -
+
は、1回から無制限の回数に一致する数量詞です。
上記の正規表現は、一致しない文字に到達するまで繰り返されます。ファイルの最初の行は次のとおりです。
root:x:0:0:root:/root:/bin/bash
次のように処理されます:
- 最初の文字は
r
です 、したがって、[a-z]
と一致します 。 -
+
次のキャラクターに移動します。 - 2番目の文字は
o
です これは[a-z]
と一致します 。 -
+
次のキャラクターに移動します。
このシーケンスは、コロンに当たるまで繰り返されます(:
)。文字クラス[a-zA-Z_-]
:
と一致しません シンボルなので、grep
次の行に移動します。
passwd
のユーザー名以降 ファイルはすべて小文字です。次のように文字クラスを簡略化しても、目的の結果を得ることができます。
$ grep -Eo '^[a-z_-]+' /etc/passwd
例:プロセスを見つける
ps
を使用する場合 プロセスをgrepするために、私たちはしばしば次のようなものを使用します:
$ ps aux | grep ‘thunderbird’
しかし、ps
コマンドはthunderbird
をリストするだけではありません 処理する。 grep
も一覧表示されます grep
なので、コマンドも実行しました パイプの後にも実行されており、プロセスリストに表示されます:
$ ps aux | grep thunderbird
val+ 2196 0.7 2.1 52 33 tty2 Sl+ 16:47 1:55 /usr/lib64/thunderbird/thunderbird
val+ 14064 0.0 0.0 57 82 pts/2 S+ 21:12 0:00 grep --color=auto thunderbird
これは、grep -v grep
を追加することで処理できます。 grep
を除外する 出力から:
$ ps aux | grep thunderbird | grep -v grep
val+ 2196 0.7 2.1 52 33 tty2 Sl+ 16:47 1:55 /usr/lib64/thunderbird/thunderbird
grep -v grep
を使用している間 新しいgrep
をフォークせずに同じ結果を達成するための、より良い方法が存在します。 プロセス:
$ ps aux | grep [t]hunderbird
val+ 2196 0.7 2.1 52 33 tty2 Sl+ 16:47 1:55 /usr/lib64/thunderbird/thunderbird
[t]hunderbird
ここでは、リテラルのt
と一致します 、および大文字と小文字が区別されます。 grep
とは一致しません 、そのため、現在はthunderbird
のみが表示されています。 出力で。
この例は、grep
がいかに柔軟であるかを示す単なるデモンストレーションです。 つまり、プロセスツリーのトラブルシューティングには役立ちません。 pgrep
のように、この目的に適したより優れたツールがあります 。
grep
を使用する ファイルまたは複数のディレクトリでパターンを再帰的に検索する場合。 grep
で正規表現がどのように機能するかを理解してください 、正規表現は強力な場合があるためです。
[Red Hat Enterprise Linuxを試してみませんか?今すぐ無料でダウンロードしてください。]