sed でキャプチャしたグループのみを出力するにはどうすればいいですか? 質問する

sed でキャプチャしたグループのみを出力するにはどうすればいいですか? 質問する

sedキャプチャされたグループのみを出力するように指示する方法はありますか?

たとえば、次のような入力があるとします。

This is a sample 123 text and some 987 numbers

そしてパターン:

/([\d]+)/

バック参照によってフォーマットされた方法で 123 と 987 の出力のみを取得できますか?

ベストアンサー1

これを機能させるための鍵は、sed出力したくないものを除外するように指示するとともに、出力したいものを指定することです。このテクニックは、探している一致の数を知っているかどうかに依存します。grep以下のコマンドは、一致数が指定されていない場合に機能します。

string='This is a sample 123 text and some 987 numbers'
echo "$string" | sed -rn 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+([[:digit:]]+)[^[:digit:]]*/\1 \2/p'

これはこう言います:

  • 拡張正規表現を使用する(-r
  • 各行を印刷することをデフォルトにしない ( -n)
  • 0個以上の非数字を除外する
  • 1桁以上の数字を含む
  • 1つ以上の非数字を除外する
  • 1桁以上の数字を含む
  • 0個以上の非数字を除外する
  • 置換(p)を1行に出力する

一般的に、 ではsed括弧を使用してグループをキャプチャし、後方参照を使用してキャプチャしたものを出力します。

echo "foobarbaz" | sed 's/^foo\(.*\)baz$/\1/'

は「bar」を出力します。拡張正規表現に-r( -EOS X の場合) を使用する場合は、括弧をエスケープする必要はありません。

echo "foobarbaz" | sed -r 's/^foo(.*)baz$/\1/'

キャプチャ グループとそのバック参照は最大 9 個まで可能です。バック参照はグループの出現順に番号が付けられますが、任意の順序で使用でき、繰り返すこともできます。

echo "foobarbaz" | sed -r 's/^foo(.*)b(.)z$/\2 \1 \2/'

「a bar a」を出力します。

GNUをお持ちの場合grep:

echo "$string" | grep -Po '\d+'

OS X を含む BSD でも動作するかもしれません:

echo "$string" | grep -Eo '\d+'

これらのコマンドは、任意の数の数字シーケンスと一致します。出力は複数行になります。

または次のようなバリエーションもあります:

echo "$string" | grep -Po '(?<=\D )(\d+)'

この-PオプションはPerl互換正規表現を有効にします。man 3 pcrepatternまたはman 3 pcresyntax

おすすめ記事