如何在linux shell中使用正则表达式从文件中提取IP地址?

Kaz*_*lis 60 regex unix linux bash command-line

如何在linux shell中通过regexp提取文本部分?可以说,我有一个文件,其中每一行都是一个IP地址,但位于不同的位置.使用常见的unix命令行工具提取这些IP地址的最简单方法是什么?

bri*_*ien 116

您可以使用grep将它们拉出来.

grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' file.txt
Run Code Online (Sandbox Code Playgroud)


Sar*_*tha 41

这里的大多数示例都匹配999.999.999.999,这在技术上不是有效的IP地址.

以下内容仅匹配有效的IP地址(包括网络和广播地址).

grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt
Run Code Online (Sandbox Code Playgroud)

如果要查看匹配的整行,请省略-o.

  • 从技术上讲,它匹配233.123.123.123,即使它前面有一个1.它不限制IP地址之前和之后的内容. (2认同)

San*_*alp 12

这在访问日志中对我来说很好.

cat access_log | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
Run Code Online (Sandbox Code Playgroud)

让我们一个一个地打破它.

  • [0-9]{1,3}表示[]中提到的范围的一到三次出现.在这种情况下,它是0-9.所以它匹配10或183等模式.

  • 其次是'.'.我们需要将其作为'.'来逃避.是一个元字符,对shell有特殊意义.

所以现在我们的模式就像'123'.'12".等等

  • 这种模式重复三次(带有'.').所以我们将它括在括号中. ([0-9]{1,3}\.){3}

  • 最后,这种模式会重演,但这次没有'.'.这就是为什么我们在第3步中单独保留它. [0-9]{1,3}

如果ips位于每行的开头,就像我的情况一样:

egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}'
Run Code Online (Sandbox Code Playgroud)

其中'^'是一个锚点,告诉你在一行的开头搜索.


JB.*_*JB. 11

我通常从grep开始,以使正则表达式正确.

# [multiple failed attempts here]
grep    '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'                 file  # good?
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file  # good enough
Run Code Online (Sandbox Code Playgroud)

然后我尝试将其转换sed为过滤掉剩下的行.(阅读完这个帖子后,你和我不再这样做了:我们将改为使用grep -o)

sed -ne 's/.*\([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\).*/\1/p  # FAIL
Run Code Online (Sandbox Code Playgroud)

那时我通常因为sed没有像其他人一样使用相同的正则表达而烦恼.所以我搬到了perl.

$ perl -nle '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ and print $&'
Run Code Online (Sandbox Code Playgroud)

无论如何,Perl很高兴知道.如果您安装了少量CPAN,您甚至可以以较低的成本使其更可靠:

$ perl -MRegexp::Common=net -nE '/$RE{net}{IPV4}/ and say $&' file(s)
Run Code Online (Sandbox Code Playgroud)