grep(1) のオプション -v が -v である理由
grep(1) ってなに
Unix な世界には grep(1) というコマンドがあります。 これはファイルの中からあるパターンを含む (パターンに一致する) 行のみを抽出して表示するコマンドです。 試しにファイル /etc/passwd から root を含む行を表示してみましょう。
% grep 'root' /etc/passwd
root:*:0:0:Charlie &:/root:/bin/csh
toor:*:0:0:Bourne-again Superuser:/root:
daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin
うん、確かに root を含む行を表示できているようです。
検索に利用するパターンには正規表現 regular expression を利用することもできます[1]。 これも試してみましょう。
% grep '^gr.p.$' /usr/share/dict/words
grape
graph
grapy
gripe
gripy
grope
一致「しない」行を抽出
grep(1) のデフォルト動作ではパターンに一致する行を表示しますが、パターンに一致しない行を表示することもできます。 そのような挙動をしてもらうためにはオプション -v を指定してあげます。 例えば、数字を含まない行を表示するには正規表現 [0-9] をパターンに指定し、オプション -v を添えます[2]。
% grep -v '[0-9]' /etc/os-release
NAME=FreeBSD
ID=freebsd
HOME_URL="https://FreeBSD.org/"
BUG_REPORT_URL="https://bugs.FreeBSD.org/"
どうして -v なのか — どうして grep なのか
しかしどうしてパターンに一致しない行を表示するオプションが -v なのでしょうか。 もっとわかりやすく reverse から -r だとか unmatch から -u だとかである方がそれっぽい感じがあります[3]。
オプション -v の謎を解き明かすためには grep(1) それ自体の名前の由来を知る必要があります。 grep という名前は Unix の古き良きエディタ ed(1) のコマンド g/RE/p
に由来します。 このコマンドは「正規表現 RE に一致する行全て (g) を表示 (p)」します。 これは grep(1) の仕事と同じです。 そして、grep(1) にオプション -v を渡したときと同じ仕事をする ed(1) のコマンドは v/RE/p
です。
grep(1) は ed(1) の機能の一部が独立してできたコマンドであり、オプション -v もまた ed(1) の機能に由来しているのでした。
おわりに
おわりです。
参考
- Brain W. Kernighan; Rob Pike. “第 1 章 初心者のための UNIX”. UNIX プログラミング環境. 石田晴久監訳; 野中浩一訳. ASCII DWANGO, 2017, p. 7–55, ISBN978-4-04-893057-4.
Discussion