次の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
答え2
gnu sedを使用しても行の有効性は制御されません。
sed -E 's/.*\.(\S+)\s+.*\.(\S+);.*/IP range is: \1-\2/'
答え3
sed -r '/^[[:blank:]]*range[[:blank:]]+/ {
s/// # delete the previous match, "range"
s/;.*//
s/[[:digit:]]+\.//g # remove digits followed by dot
s/[[:blank:]]+/-/
s/^/IP range is: /
}' <<END
range 1.1.1.10 1.1.1.100;
END
IP range is: 10-100
答え4
$ echo ' range 1.1.1.10 1.1.1.100;' |
sed -Ene 's/^[[:blank:]]*range [0-9.]*\.([0-9]+) [0-9.]*\.([0-9]+);.*/IP range is: \1-\2/p'
IP range is: 10-100
部分:
^[[:blank:]]* any blanks at start of line
[0-9.]*\. numbers and dots, ending with a dot
([0-9]+) capture the following numbers
[0-9.]*\.([0-9]+) same, again
\1 and \2 put back the captured groups
s///p print if the substitution matched