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

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 grepman の後2行を表示
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -A2 -- ^man$
man
lp
mail
GNU grepman の前2行を表示
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B2 -- ^man$
sync
games
man
GNU grepman の前後それぞれ2行を表示
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -C2 -- ^man$
sync
games
man
lp
mail
GNU grepman の前1行後2行を表示
$ awk -F: '{if ($3 < 1000) {print $1 }}' /etc/passwd | head | grep -B1 -A2 -- ^man$
games
man
lp
mail
GNU grepman の後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 が指定可能でこれでマッチ部分から最後まで表示できます.

grepman の後すべてを表示
$ 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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です