首页 > 解决方案 > 在 grep 和 sed 中正确使用正则表达式开关

问题描述


我已经学习 SED 和 GREP 几个星期了。通常我使用 ATOM 编辑器来构建正则表达式,它对我有很大帮助。现在我只需要几分钟就可以买一个。
但是当我尝试使用 ubuntu 终端对数据文件使用相同的正则表达式时,事情开始变得丑陋。

有人可以提供带有 grep 和 sed 的精确开关,但也有限制(例如 - GNU SED 不能将 \d 用于数字,而是使用 [0-9])。
让我们以下面的文本和要求为例:
192.168.10.10,fe80:0:0:0:bcf6:c04e:cb99:6909,10.0.170.11
172.16.32.44
fe80:0:0:0:84a5:1d2e:55d1:ecf,192.168.4.50
fe80:0:0:0:84a5:1d2e:55d1:ec1
10.10.101.22

在我绞尽脑汁几个小时之后,我终于可以grep -P '(\d{1,3}\.){3}\d{1,3}'打印出唯一的 IPV4 地址了。但这是 PERL 正则表达式开关。所以现在我对使用什么和不使用什么感到非常困惑。
请帮我为以下要求构建完整的 SED 和 GREP 命令(假设输入是文件):

1- Print only IPV4 addresses using GREP.
2- Print everything except IPV4 addresses using GREP.
3- Print only IPV4 addresses using SED.
4- Print everything except IPV4 addresses using SED.
5- Replace IPV4 addresses with --- using SED.
6- Replace everything except IPV4 addresses using SED.

标签: linuxsedterminalgrep

解决方案


来自问题 Validating IPv4 addresses with regexp

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]?)'

正则表达式看起来很适合用作扩展正则表达式。

1- 使用 GREP 仅打印 IPV4 地址。

grep -Eo "$ipv4"

2- 使用 GREP 打印除 IPV4 地址之外的所有内容。

我相信打印 grep 行的“除了”部分是不可能的。

3- 使用 SED 仅打印 IPV4 地址。

使用适当的正则表达式编写一个sed脚本,在每个 ipv4 地址后添加一个换行符。然后将每个非换行字符串替换为 ipv4 后跟换行符,仅将 ipv4 替换为换行符。从模式空间中删除换行符并打印它。伴随着一些东西:

sed -E "s/($ipv4)/&\n/g; s/$/\n/; s/([^\n]*)($ipv4)\n/---\2\n/g; s/\n\n/\n/; s/\n//g"

4- 使用 SED 打印除 IPV4 地址之外的所有内容。

sed -E "s/$ipv4//g"

5- 使用 SED 将 IPV4 地址替换为 ---。

sed -E "s/$ipv4/---/g"

6- 使用 SED 替换除 IPV4 地址之外的所有内容。

作为第 3 点,但不是用 ipv4 替换非换行字符串,然后用 ipv4 和换行符替换换行符,而是删除 ipv4 并保留非换行符部分。伴随着一些东西:

sed -E "s/($ipv4)/&\n/g; s/$/\n/; s/([^\n]*)($ipv4)\n/\1---\n/g; s/\n\n/\n/; s/\n//g"

-E-r选项)` 在技术上是对 POSIX sed 的扩展。我怀疑你会找到没有它的实现——如果你这样做了,请将正则表达式转换为基本的正则表达式,它应该可以正常工作。


推荐阅读