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
( -E
OS 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
。