ugrepでマッチ行以降全て表示

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 に最後まで表示できるオプションがあるのに気づいたのでメモしておきます．

Grep – GNU Project – Free Software Foundation

Home · Genivia/ugrep Wiki

The ugrep file pattern searcher

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
news

GNU grep で man の後2行を表示

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -A2 -- ^man$
man
lp
mail

GNU grep で man の前2行を表示

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B2 -- ^man$
sync
games
man

GNU grep で man の前後それぞれ2行を表示

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -C2 -- ^man$
sync
games
man
lp
mail

GNU grep で man の前1行後2行を表示

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B1 -A2 -- ^man$
games
man
lp
mail

GNU grep で man の後99行を表示(実際はそんなに行数がないので最後まで表示)

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -A99 -- ^man$
man
lp
mail
news

ugrep を試す

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 device

tacで逆順にして -1 で切り取ったと再度tacで逆順に

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | tac | ugrep -A-1 -- ^man$ | tac
root
daemon
bin
sys
sync
games
man

ugrepは他にも対話型問い合わせの機能(-Q)やインデックスを作成して検索を高速化(-indexer)する機能など様々な機能が含まれています．
もっと使いこなしていきたいところです．

別解: sed, awk, perl

sed

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | sed -n '/^man$/,$p'
man
lp
mail
news

awk

$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | awk '/^man$/',0
man
lp
mail
news

perl

$ 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