IP アドレスと一致しない文字列をダミー IP アドレスに置き換えるにはどうすればよいでしょうか?

IP アドレスと一致しない文字列をダミー IP アドレスに置き換えるにはどうすればよいでしょうか?

IP アドレスのリストを含むファイルがありますが、一部の文字列は IP アドレスではないため、そのような文字列をダミーの IP アドレスに置き換えたいと考えています。

私はこれを使用してgrepIP を検索していますが、一致しないものをダミー IP アドレスに置き換える方法がわかりません。 で実行できると思いますsed。いくつか試しましたが、どれも機能しませんでした。

cat file.txt | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

ファイル内の IP アドレスと一致させるためにこれを使用していますsedが、非 IP アドレスをダミー IP に置き換える方法がわかりません。

sed -rn '/([0-9]{1,3}\.){3}[0-9]{1,3}/p' file.txt

入力:

192.168.10.20
00 03
10.28.214.5
192.168.10.40
BF
192.168.10.50

望ましい出力:

192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

ありがとう!

答え1

正規表現は、ないIPv4 のドット区切りの 4 つのアドレスですが、見た目は IPv4 に似ています (例256.256.256.256: IPv4 アドレスによく似ていますが、異なります)。

一致するもののみ有効IPv4 アドレスの場合は、次のような正規表現を使用する必要があります。

(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

または(Perl 風の?:非キャプチャグループ修飾子なし):

((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

そして、これは適切に固定される必要があります。たとえば、両端に と 、または^と を$使用します。\b\<\>

見る:正規表現クックブック著者:Jan Goyvaerts、Steven Levithan、出版:O'Reilly Media, Inc.

例えば

$ sed -E '/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/!s/.*/192.168.0.0/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50
$ perl -p -e 's/.*/192.168.0.0/ unless m/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

どちらも、行が有効な IPv4 アドレスと一致しない限り、入力行全体を 192.168.0.0 に変更します。

個人的には、Perlの正規表現::共通モジュールは、一般的なパターン マッチング タスク用の正規表現の大規模なコレクションであり、 と呼ばれるハッシュで便利に利用できます%RE

$ perl -MRegexp::Common -p -e 's/.*/192.168.0.0/ unless m/^$RE{net}{IPv4}$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

答え2

注: IPv4 アドレスに選択した正規表現に欠陥があると他の人が指摘しています。これについては他の場所で十分に説明されているので、ここでは触れません。

sedを使うことができますc!( ) が RE に一致しない行に hange コマンドを実行します (例:

$ sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c\
192.168.0.0
' file.txt
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

GNU sedを使えば、次のように簡略化できます。

sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c192.168.0.0' file.txt

答え3

sed '/^\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\}$/!s/.*/192.168.0.0/' data

行が有効な IPv4 アドレスでない場合は、現在の行を : に置き換えます192.168.0.0

ダミー アドレスの代わりに別の値を使用することをお勧めします192.168.0.0が、これはユーザーとユーザーのニーズ次第です。

または、次のように同じですawk:

awk '!/^([0-9]{1,3}\.){3}[0-9]{1,3}$/ {$0="192.168.0.0"}1' data

またはperl

perl -MNet::IP -ple '$_ = "192.168.0.0" unless new Net::IP($_)' data

答え4

Perl

  • 1 桁から 3 桁の数字で構成されるオクテットの正規表現を定義します。ただし、1 桁の数字でない限り、先頭が 0 以外になるという制約があります。
  • 行がドットで区切られた正確に 4 つのオクテットで構成されていることを確認します。
  • 線をドットで分割し、すべてのタプルが 256 未満であることを確認します。
dummy=192.168.0.0 \
perl -MList::Util=all -lpe '
  $octet //= qr/(?!0\d)\d{1,3}/;

  /^$octet(?:[.]$octet){3}$/ &&
   all { $_<256 } split /[.]/ or
     $_ = $ENV{dummy};
' file

関連情報