
ファイルでipv4を探す必要があります。問題は、同じ行に異なる単語IPがある場合、スクリプトがそれを印刷しないことです。これは私のスクリプトです。
#!/bin/bash
if [ -e ip.txt ]
then
grep -E '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ip.txt
else
echo "file not found"
fi
今、このようなものがある場合、スクリプトはIPを印刷しません。
198.54.34.6 text
答え1
コマンドからおよびを削除^
し、grepコマンドのフラグを使用します。つまり:$
-o
grep -Eo '(^| )(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($|[[:space:]])'
例:
echo 'some text 198.54.34.6 and test' | grep -Eo '(^| )(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($|[[:space:]])'
出力は次のとおりです
198.54.34.6
空白が発生し、tr
たとえば空白を削除してみてくださいcommand1 | tr -d " "
。
答え2
^
そして、$
行の始まりと終わりでそれぞれ一致するので、IPアドレスを持つ行は行の始まりと終わりの両方にある場合にのみ一致します。つまり、IPアドレスはいフルライン。
これで、完全なIPアドレスを含む行を一致させるには言葉、どこ性格スペースで区切られている場合は、次のものを使用できます。
d='[01234567890]'
n="($d|[123456789]$d|1$d$d|2[01234]$d|25[012345])"
grep -E "(^|[[:blank:]])$n\.$n\.$n\.$n([[:blank:]]|\$)" ip.txt
(ここでは0123456789だけでなく、よく一致するもの[0-9]
に置き換えます。)[0123456789]
[0-9]
grep
出力されますので参考にしてくださいワイヤーそのゲーム。行の一部のみを出力するには、sed
または(ストリームエディタ)などを使用するか、GNUのようないくつかの実装perl
の非標準拡張を使用する必要があります。grep
-o
grep
ここでは否定予測演算子が使用されます((?<!\H)
意味「空白以外の文字が前に来ない場合」、(?!\H)
同じですが前方ではなく前方に探して(?1)
最初のグループのREを呼び出すと、(...)
すべてのPerlに似た演算子がアクティブになります-P
。
grep -Po '(?<!\H)(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)(?!\H)' ip.txt
これは次のとおりです。
perl -lne 'print for
/(?<!\H)(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)(?!\H)/g'
答え3
-o
IPv4のみを印刷するには、grepオプションと一致するものを抽出します。
より簡単な例として、次のようにすることができます。
$ echo "this is a simple test to extract 123.234.34.5 as an IP" |
grep -o '[0-9.]*'
123.234.34.5
しかし、これは失敗するでしょう。正確にIPv4と一致します。
正規表現を使用してIPを一致させるのは少し複雑です。正規表現は数値範囲を理解せず、テキストのみを理解します。 0から255の間の数値を次のように一致させることができます(スペースとコメントを無視する正規表現)。
25[012345] | # the numers 250 - 255 or
2[01234](?P<digit>[0123456789]) | # 200 - 249 or
1(?&digit){2} | # 100 - 199 or
#0? # Allow leading zero
[1-9](?&digit) | # 10 - 99 or
#0{0,2} # Allow leading zeros
(?&digit) # 0 - 9
先行ゼロを含めるには、最初の列コメントを削除します。
重複を避けるには、[0-9]
明示的な数値範囲を使用し(他の言語での数値一致を避けるため)、一致する各グループの名前を指定してください。 PCREでは、「名前付きキャプチャグループ」を使用できます。
(?P<byte> # Define this as one full byte value.
25[012345] | # the numers 250 - 255 or
2[01234](?P<digit>[0123456789]) | # 200 - 249 or
1(?&digit){2} | # 100 - 199 or
#0? # Allow leading zero
[1-9](?&digit) | # 10 - 99 or
#0{0,2} # Allow leading zeros
(?&digit) # 0 - 9
) # close one full byte definition
(\.(?&byte)){3}
その後、次のように先行点といくつかの先行マーカーと後続マーカーを使用してバイト定義を3回再利用できます。このリンクに表示されます
\b
必要に応じて、前後のマーカーはより単純な「単語の境界」()になります。この他のリンクに表示されます
シェルでgrep PCRE正規表現を使用して、次のようにコマンドを作成できます。
$ grep -oP '(?xm)(?<=^|[^01234567890.])(?P<byte>25[012345]|2[01234](?P<digit>[0123456789])|[01]?(?&digit){1,2})(\.(?&byte)){3}(?=[^01234567890.]|$)' <<<"$a"
1.2.3.4
11.22.33.44
123.234.34.5
1.1.192.168
123.234.34.123
123.234.34.123
1.2.3.255
255.255.255.255
1.1.168.192
1.14.2.90
1.2.3.4
テスト文字列に次のものが含まれているとします。
$ a='1.2.3.4
11.22.33.44
123.234.34.5
1.1.192.168
text 123.234.34.123 more text
text123.234.34.123more text
1.2.3.255
1.2.3.256
255.255.255.255
256.2.3.4
1123.234.34.123
123.234.34.1235
.123.234.34.123
123.234.34.123.
not 1.1.168.192 in 1.1.168.192.in-addr.arpa.
not 1.14.2.90 in xserver-common_1.14.2.901-2_all.deb
1.2.3.4'
答え4
この正規表現はIPアドレスを取得し、grep -P
PCRE正規表現エンジンをオンにして-o
一致するテキストのみを返すIPv4アドレスの非常に正確な正規表現です。
grep -Po '\b((?:25[0-5]|[2][0-4][0-9]|[1][0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|[2][0-4][0-9]|[1][0-9]{2}|[1-9][0-9]|[0-9])\b' ip.txt
この正規表現の説明については、次を参照してください。https://regexr.com/4kjg4
25[0-5] | # 250 - 255
[2][0-4][0-9] | # 200 - 249
[1][0-9]{2} | # 100 - 199
[1-9][0-9] | # 10 - 99
[0-9] | # 0 - 9