web-dev-qa-db-ja.com

sed:一致するグループのみを印刷します

最後の2つの数字(1つのint、1つのfloat、その後にオプションの空白文字)をつかみ、それらだけを表示したいのです。

例:

foo bar <foo> bla 1 2 3.4

印刷する必要があります:

2 3.4

これまでのところ、私は以下の通りです:

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/replacement/p' 

私にくれる

foo bar <foo> bla 1 replacement

しかし、それをグループ1に置き換えようとすると、行全体が印刷されます。

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/\1/p' 

グループ内の正規表現に一致する行のセクションだけを印刷する方法はありますか

111
mort

行全体を一致させるため、正規表現の先頭に.*を追加してください。これにより、行全体がグループの内容に置き換えられます。

echo "foo bar <foo> bla 1 2 3.4" |
 sed -n  's/.*\([0-9][0-9]*[\ \t][0-9.]*[ \t]*$\)/\1/p'
2 3.4
114
iruvar

grepは抽出に適したツールです。

あなたの例とあなたの正規表現を使って:

kent$  echo 'foo bar <foo> bla 1 2 3.4'|grep -o '[0-9][0-9]*[\ \t][0-9.]*[\ \t]*$'
2 3.4
60
Kent

また別の選択肢として、私はawkを使っています。

echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'

これは入力(ここではSTDINを使っていますが、あなたの入力は簡単にファイルになるかもしれません)をスペースに分割してから、最後から二番目のフィールド、そして最後のフィールドを出力します。 $NF変数は、スペースで展開した後に見つかったフィールドの数を保持します。

これの利点は、最後の2つのフィールドの前にあるものが変更されても、最後の2つのフィールドだけが動作し続けることを望んでいる限り、問題にならないことです。

9
chooban

Cutコマンドは、このような状況に合わせて設計されています。任意の区切り文字を「カット」してから、どのチャンクを出力するかを指定できます。

例えば:echo "foo bar <foo> bla 1 2 3.4" | cut -d " " -f 6-7

2 3.4が出力されます。

-d区切り文字を設定します

-fは、出力する「フィールド」の範囲を選択します。この場合、元の文字列の6番目から7番目のチャンクです。 6,7のように範囲をリストとして指定することもできます。

3
carlin.scott