マッチした部分だけを抽出したい

テキストから特定のパターンにマッチした部分だけを抽出したい。

通常のgrepコマンドはマッチした行全体を表示するため、マッチした部分以外の情報も含まれてしまう。

$ echo "価格は1000円です" | grep "[0-9]\+"
価格は1000円です

-o オプションでマッチした部分のみを表示

grepコマンドの-oオプションを使用するとマッチした部分のみを表示する。

$ echo "価格は1000円です" | grep -o "[0-9]\+"
1000

複数マッチする場合

-oオプションは1行に複数マッチする場合、それぞれを別の行として出力する。

$ echo "100円と200円と300円" | grep -o "[0-9]\+"
100
200
300

URLから特定の部分を抽出する

-oオプションは正規表現と組み合わせて使用すると便利だ。

例えばURLからドメイン部分のみを抽出する際は-Pオプションと\Kを使う。

$ echo "https://example.com/path/to/page" | grep -oP "https?://\K[^/]+"
example.com

-PオプションでPerl互換の正規表現を使用し、\Kで前方部分をマッチから除外する。

macOSでの-Pオプション

macOSのBSD版grepでは-Pオプション(Perl互換の正規表現)がサポートされていない。macOSでPerl互換の正規表現を使用するには、HomebrewでGNU版grepをインストールする。

$ brew install grep

インストール後、ggrepコマンドとして使用できる。

$ echo "https://example.com/path/to/page" | ggrep -oP "https?://\K[^/]+"
example.com

IPアドレスを抽出する

ログファイルからIPアドレスだけを抽出する際にも便利。

$ echo "接続元: 192.168.1.100 から接続がありました" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
192.168.1.100

-Eオプションで拡張の正規表現を使用している。このパターンは簡易的なものであり、999.999.999.999のような不正なIPアドレスにもマッチする点に注意が必要。

メールアドレスを抽出する

テキストからメールアドレスを抽出する例。

$ echo "連絡先: info@example.com または support@example.jp" | grep -oE "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
info@example.com
support@example.jp