web-dev-qa-db-ja.com

一連の文字列からIPアドレスを選択して印刷する方法は?

IPアドレスを含む文章があります。例えば、

This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.

上記の文から、IPアドレスのみを印刷したいと思います。これどうやってするの? sedでこれを行うことができると聞きました

3
Anandu M Das

可能ですが、エレガントではありません。

echo 'This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.' \
| sed 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/'

[0-9]は任意の数字に一致し、\{1,3\}は1〜3回繰り返すことができることを意味します。 \.はドットに一致します。 IP全体は\(...\)括弧でキャプチャされ、前後にあるものは.*、つまり0回以上繰り返されるものと一致します。一致する文字列全体(つまり、行全体)は、最初の一致するグループの内容に置き換えられます。

変数を導入することで読みやすくすることができます:

n='[0-9]\{1,3\}'
... | sed "s/.*\($n\.$n\.$n\.$n\).*/\1/"

IPが見つからない場合、文字列全体を出力します。また、256.512.999.666などの無効なIPもチェックしません。

7
choroba

これはgrepソリューションです。

echo "$sentence" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
  • -o一致する部分のみを印刷します
  • -Eは拡張正規表現に切り替わります
  • パターンは、すべての数字([0-9])に1回以上(+)、次にドット(\.)、さらに数字に一致します...

ここでPerlを使用した別のソリューション:

echo "$sentence" | Perl -l -ne '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ && print $&'
  • -lは行末記号(改行)を指定しました
  • -nは、echoで指定された入力をループします(複数行になる場合があります)
  • -eコードが続きます
  • perlコード内の正規表現は、上記のgrepソリューションとほぼ同じです。
6
chaos

grepの次のコマンドを使用します。

grep -Eo '[0-9.]+ ' file

またはさらに良い:

grep -oP '\d+\.\d+\.\d+\.\d+' file

または

grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}" file
2
αғsнιη

私はgrepを使用します:

echo 'This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.' | grep -oE '((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){3}((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]))'

これは、他の回答とは異なり、有効なIPアドレスのみを出力します

1
Jiří Gracík

python 3インタープリターでこれを行います。この111.111.111.111形式のテキストを取得するだけでなく、有効かどうかもチェックします。

>>> import re
>>> import ipaddress
>>> text = "This sentence contains an ip number 1.2.3.4 and 111.111.111.111 451.976.897.786 port number 50, i want to print the IP address only."
>>> foo = re.findall(r'(?<!\S)(?:\d{1,3}\.){3}\d{1,3}(?!\S)', text)
>>> foo
['1.2.3.4', '111.111.111.111', '451.976.897.786']
>>> for i in foo:
...     try:
...         ipaddress.ip_address(i)
...     except:
...         pass
... 
IPv4Address('1.2.3.4')
IPv4Address('111.111.111.111')

python 3インタープリターを取得するには、ターミナルでpython3コマンドを入力します。

0
Avinash Raj

Chorobaの答えの拡張:

新しい行を印刷せず、IPのみを印刷する場合:

$ echo -e 'This sentence contains an ip number 1.2.3.4 and port number 50, \ni want to print the IP address only.\n One more IP is 1.24.53.3.' \
| sed -n 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/1p'

出力:

1.2.3.4
1.24.53.3

説明:

-n flag is for quiet / silent.
 p print the replaced text
0
snoop

RegExpと組み合わせたAWKは、行の一部の処理に非常に適しています。

ワンライナーベローズの基本的な考え方は、ラインをforループし、最大4回繰り返される4つの数字とドットの存在を確認することです。同時に、ポート番号について2〜4回繰り返される数字を確認できます。

awk '{for(i=1;i<=NF;i++) { if ($i~/[[:digit:]\.]{4}/) printf $i; if ( $i~/[[:digit:]]{2,4}/) printf ":"$i  }}'

サンプル実行

$ echo "This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only." |  awk '{for(i=1;i<=NF;i++) { if ($i~/[[:digit:]\.]{4}/) printf $i; if ( $i~/[[:digit:]]{2,4}/) printf ":"$i  }}'

1.2.3.4:50,

あなたの文章には50が含まれており、分離せずに一緒に印刷されますが、gsub(/[[:punct:]]/,"")は必要に応じて削除できます。

0