grepコマンドにマッチした部分から指定行を表示する機能があります.
例えば以下の例ではマッチした部分から後ろ11行を表示.
$ man grep | grep 'Context Line Control' -A 11
Context Line Control
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is
given.
-B NUM, --before-context=NUM
Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is
given.
-C NUM, -NUM, --context=NUM
Print NUM lines of output context. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.マッチした部分以降全てを表示したいことがあります.行数を確認するのが面倒だったりするので -A 999 とかやりがちです.
ugrep に最後まで表示できるオプションがあるのに気づいたのでメモしておきます.
DebianではGNU grepは grep パッケージで,ugrep は ugrep パッケージで提供されています.
導入
$ sudo apt install grep $ sudo apt install ugrep
GNU grep を試す
適当なテキスト
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head
root
daemon
bin
sys
sync
games
man
lp
mail
newsGNU grep で man の後2行を表示$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -A2 -- ^man$
man
lp
mailGNU grep で man の前2行を表示$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B2 -- ^man$
sync
games
manGNU grep で man の前後それぞれ2行を表示$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -C2 -- ^man$
sync
games
man
lp
mailGNU grep で man の前1行後2行を表示$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B1 -A2 -- ^man$
games
man
lp
mailGNU grep で man の後99行を表示(実際はそんなに行数がないので最後まで表示)$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -A99 -- ^man$
man
lp
mail
newsugrep を試す
ugrep もGNU grepと同じように -A/-B/-C が使えます.そして -A 利用時には行数に -1 が指定可能でこれでマッチ部分から最後まで表示できます.
grep で man の後すべてを表示$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | ugrep -A-1 -- ^man$
man
lp
mail
news-B には使えない$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | ugrep -B-1 -- ^man$
ugrep: warning: exception while searching (standard input): Inappropriate ioctl for devicetacで逆順にして
-1 で切り取ったと再度tacで逆順に$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | tac | ugrep -A-1 -- ^man$ | tac
root
daemon
bin
sys
sync
games
manugrepは他にも対話型問い合わせの機能(-Q)やインデックスを作成して検索を高速化(-indexer)する機能など様々な機能が含まれています.
もっと使いこなしていきたいところです.
別解: sed, awk, perl
sed
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | sed -n '/^man$/,$p'
man
lp
mail
newsawk
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | awk '/^man$/',0
man
lp
mail
newsperl
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | perl -ne "print if /^man$/ .. eof;"
man
lp
mail
news環境
$ dpkg-query -W grep ugrep sed gawk perl gawk 1:5.3.2-1 grep 3.11-4 perl 5.40.1-3 sed 4.9-2 ugrep 7.4.2+dfsg-1 $ lsb_release -dr Description: Debian GNU/Linux 13 (trixie) Release: 13 $ arch x86_64