🔀
grepの結果を反転させる方法
概要
grep コマンドについて
- 出力される行を反転させる方法
- 終了ステータスを反転させる方法
を説明する。なお、エラーになる場合については考慮しない。
出力される行を反転させる
マッチする行を出力するのではなく、マッチしない行を出力させるには、-v オプションをつける。
$ printf "abc\nbcd\ncde\n"
abc
bcd
cde
$ printf "abc\nbcd\ncde\n" | grep b
abc
bcd
$ printf "abc\nbcd\ncde\n" | grep -v b
cde
終了ステータスを反転させる
マッチする行がある場合に0以外の終了コード、マッチする行がない場合に終了コード0にする。
入力が1行と仮定できる場合
入力が1行ならば、その1行が条件にマッチするか、しないかで終了コードが決まる。
$ echo -n "abc" | grep -q c ; echo $?
0
$ echo -n "abc" | grep -q d ; echo $?
1
したがって、-v オプションをつけることで終了ステータスを反転できる。
$ echo -n "abc" | grep -q -v c ; echo $?
1
$ echo -n "abc" | grep -q -v d ; echo $?
0
任意行の入力の場合
入力が1行と仮定できない場合、すなわち
- 入力が0行になり得ること
- 入力が2行以上になり得ること
の考慮も必要な場合には、-v オプションでは終了ステータスが反転するとは限らない。以下は反例である。
$ echo -n | grep -q a ; echo $?
1
$ echo -n | grep -q -v a ; echo $?
1
$ printf "abc\nbcd\ncde" | grep -q b ; echo $?
0
$ printf "abc\nbcd\ncde" | grep -q -v b ; echo $?
0
終了ステータスを反転するには、パイプラインの先頭に ! を付ければ良い。
$ echo -n | grep -q a ; echo $?
1
$ ! echo -n | grep -q a ; echo $?
0
$ printf "abc\nbcd\ncde" | grep -q b ; echo $?
0
$ ! printf "abc\nbcd\ncde" | grep -q b ; echo $?
1
まとめ
grepコマンドに関する二種類の反転について説明した。
- grepの-vオプションで出力を反転する
- シェルの!でコマンドの終了ステータスを反転する
後者はコマンドの出力に特定の文字列が含まれた場合にCIを失敗させるなどに活用できる。
確認環境
文中のコマンドの実行は以下の環境を用いた
$ bash --version
GNU bash, version 5.0.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ grep --version
grep (GNU grep) 3.4
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Mike Haertel and others; see
<https://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.
Discussion