grep では 後方参照ができないので、代替案を考えることになる。
方法1基本的な方法 -o
マッチした箇所だけを取り出す -o
を使って、マッチした箇所だけを取り出す。
cat out.txt | \grep -Po 'Abc.*Xyz'
方法2 先読み+あとよみ
先読み・後ろ読みにマッチした箇所だけを取り出す -o
を組み合わせる。
cat out.txt | \grep -Po '(?<=Abc).*(?=Xyz)'
方法3 perl や ruby などワンライナーを使う
もはや、grep ではないが、代替案としては行ける
cat out.txt | ruby -pe 'sub(/^Abc(.*)Xyz/, "\\1")'
方法4 sed で置換する
もはや、grep ではない。が代替案としては行けるし、sedは手軽に使える。
cat out.txt | sed -nr 's/Abc(.+)Xyz/\1/p'
ただし、sedでは、非マッチ箇所が残る。 sedはマッチした箇所を置換するだけなので、マッチしない箇所は出力される。
そこで、-n
をつけて、マッチした箇所だけを表示するようにする。
方法5 bashの機能を使う。
[[ takuya =~ taku(.+) ]] echo ${BASH_REMATCH[@]}
bash に正規表現のマッチングが追加されている。マッチした箇所をBASH_REMATCH
変数で取り出せるので、後方参照の代わりになる。
後方参照を使いたいような場面はシェルスクリプトを作ってるときだろうから bashの正規表現の各種機能で事足りることがほとんどである。
感想
grep と正規表現と後方参照の代替は、「後方参照」を「置換」と考えて、sedで行うのがベターだと思われる。
grep でマッチした箇所を取り出す -o
などと併せて覚えおけば、ちょっとしたフィルタ処理やデータを整形するときに使えるのではないかと思う。
後方参照=置換と考えるのが大事。マッチした箇所を取り出す。だと限界がある。
2023-05-23
bash rematchを追加