1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

もう `sed` や `awk` に逃げない。`grep -oP` で実現する「欲しい文字列だけをピンポイントで引っこ抜く」黒魔術

1
Posted at

はじめに:不格好なパイプ地獄と自己嫌悪

APIのレスポンス(JSON風テキスト)やHTMLのソースコードから、「id="12345"12345 の部分だけを取り出したい」。
そんな時、昔の私はこんな「不格好なワンライナー」を量産していました。

# 1. まず grep で行を出す
# 2. cut とかで不要な前を取り除く
# 3. sed で不要な後ろを取り除く
$ grep 'id="' data.txt | cut -d'"' -f2

「動けばいい」とはいえ、後から見返すと何をしているか全く分からないパイプ地獄。フォーマットが少し変わった瞬間に盛大にぶっ壊れる脆さ。
「もっとスマートに、欲しい文字列の部分だけ をピンポイントで引っこ抜けないのか…?」
実は、grep にはそれを1発のコマンドで実現する「黒魔術(高度な正規表現)」が隠されていました。
それが -oP の組み合わせ です。

技術解説:不要な部分を削ぎ落とす「刀」と、最強の「目」

普通の grep は「行全体」を出力しますが、これを「マッチした部分だけ」に絞るのが -o(Only matching)オプションです。
しかし、ただ -o を使うだけでは「検索キーワードそのもの」しか出力されないため、あまり意味がありません。
ここで最強の相棒となるのが、-P(Perl-compatible regular expressions:Perl互換正規表現)です。この -P を使うことで、正規表現の最高峰である「肯定先読み/後読み」という黒魔術が使えるようになります。

黒魔術の呪文:「◯◯の後ろ」かつ「△△の前」だけを取り出す

例として、User ID is: 98765, active: true という文字列から 98765 の数字部分だけを抜き出したいとします。
ここで使うのが 後読み (?<=...)(〜の直後にある)と、先読み (?=...)(〜の直前にある)です。

# -o: マッチした部分だけ出力
# -P: Perl互換正規表現を有効化
$ echo "User ID is: 98765, active: true" | grep -oP '(?<=User ID is: )\d+(?=,)'

出力結果:

98765

図解:先読み・後読みの仕組み

この正規表現は、以下のように解釈されます。

  1. (?<=User ID is: ) = 「User ID is: 」という文字の後ろにある…
  2. \d+ = 連続した数字(これが本当に抽出したい中身
  3. (?=,) = かつ、,(カンマ)のにあるもの
    先読みと後読みの部分は**「条件としてチェックするが、抽出(出力)結果には含めない」**という特殊な働きをします。
    だから -o と組み合わせることで、真ん中の「欲しい部分」だけが綺麗にポロッと落ちてくるのです。

伏線回収と読後感:ワンライナーの芸術家へ

この -oP の黒魔術(先読み・後読み)をマスターして以降、私の書くシェルスクリプトから cutsed が幾重にも連なる不恰好なパイプ処理は一掃されました。
どのような複雑なログフォーマットからでも、前後を条件で挟み撃ちにするだけで、目的の値だけをスマートに、かつ堅牢に抽出できるようになったのです。
「ただの文字検索ツール」だと思っていた grep が、実は最強の「テキスト抽出マシーン」だったと気づいた時の衝撃。
明日から、文字列のパースで cut を打ちそうになったら、一度手を止めて grep -oP の黒魔術を唱えてみてください。ワンライナーが一段階上の、芸術的な美しさに到達しますよ。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?