sed - ドットの各インスタンスの前のすべての数字を削除します。

sed - ドットの各インスタンスの前のすべての数字を削除します。

次のIP範囲の前の数字を削除しようとしています。

range 1.1.1.10 1.1.1.100;

次の出力を表示したい。

IP range is: 10-100

このコマンドを試した場合:

echo '  range 1.1.1.10 1.1.1.100;' | sed -rn '/^\s*range/ s/.*\.([0-9]{1,3})\s*.*\.([0-9]{1,3});/IP range is: \1-\2/p'

私は得る:

IP range is: 1-100

しかし、このコマンドを試してみると

echo '  range 1.1.1.10 1.1.1.100;' | sed -rn '/^\s*range/ s/.*\.([0-9]{1,3})\s*.*([0-9]{1,3});/IP range is: \1-\2/p'

私は得る:

IP range is: 10-0

私は何を逃したことがありませんか?私が見るには、sedが最初のアドレスに最後のオクテットが現れた直後にスペースを見つけないようです。

ベストアンサー1

あなたの問題は貪欲に関連しています.*。 Perlでもこれを行うことができますが、sedより簡単です。

$ echo 'range 1.1.1.10 1.1.1.100;' | perl -ne 'printf("IP range is %d-%d\n", (/\.(\d+)[^.]/g))'
IP range is 10-100

Perlスクリプトは、IPアドレスの末尾にある数字を一致させ、フォーマットされたprintf()出力文字列を印刷するために2つの整数で返します。

パール正規表現

/\.(\d+)[^.]/g

前にドットがあるが、後にドットが出ないすべての数値セットをキャプチャします。


sed実際に一度に交換を行う必要はありません。

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);/\1/'
range 1.1.1.10 100

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);/\1/' -e 's/[^ ]*\.([0-9]+) /\1-/'
range 10-100

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);/\1/' -e 's/[^ ]*\.([0-9]+) /\1-/' -e 's/range/IP & is/'
IP range is 10-100

最終sedスクリプト:

s/[^ ]*\.([0-9]+);/\1/;   # Isolate last number in range
s/[^ ]*\.([0-9]+) /\1-/;  # Isolate first number in range, add dash
s/range/IP & is/;         # Sort out text at start

点検後短縮可能

s/[^ ]*\.([0-9]+)[^.]/-\1/g
s/range -/IP range is /

それは

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+)[^.]/-\1/g' -e 's/range -/IP range is /'
IP range is 10-100

おすすめ記事