BASH - sed 替换 IP 变体

BASH - sed 替换 IP 变体

我已经很久没有在这里发过问题了。需要一些帮助才能让我的 sed 工作。我尝试了各种形式的 sed 选项,但似乎无法让它工作。我有一个文件,里面全是“192.*”,需要任何类型的 IP 地址,只要其中有与“192”类似的内容,全部删除,但我需要保留其他所有内容。看起来像这样的东西:

+ : root : 192.,local,10.
+ : root : local,192.
+ : root : local,192.,10.
+ : root : local,10.33.45.34,192.168.22.100
+ : root : local,192.168.22.100,10.33.45.34
+ : root : local,192.168
+ : root : local,192.168,10.

我尝试过的项目:

sed -e 's/,192.*$//g' -e 's/,192.*,//g' -e 's/192.,//g'
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.,//' 
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.*,//' 
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.,//'

我快要疯了,所以很感激能得到一些帮助。

提前致谢。

答案1

我已经检查过这个 sed 并且它几乎可以正常工作

sed -e 's/,\?192\(\.\([0-9]\{0,3\}\)\)\{0,3\},\?//g'

例如:

[batchhercules@hercules ~]$ cat example.txt | sed -e 's/,\?192\(\.\([0-9]\{0,3\}\)\)\{0,3\},\?//g'
+ : root : local,10.
+ : root : local
+ : root : local10.
+ : root : local,10.33.45.34
+ : root : local10.33.45.34
+ : root : local
+ : root : local10.

正如您在第 3、5、7 行看到的,它替换了两个逗号,这很糟糕。因此升级为:

sed -e 's/,192\(\.\([0-9]\{0,3\}\)\)\{0,3\}//g' -e 's/192\(\.\([0-9]\{0,3\}\)\)\{0,3\},//g'

对于你的例子来说,这将非常有效:

[batchercules@hercules ~]$ cat example.txt | sed -e 's/,192\(\.\([0-9]\{0,3\}\)\)\{0,3\}//g' -e 's/192\(\.\([0-9]\{0,3\}\)\)\{0,3\},//g'
+ : root : local,10.
+ : root : local,10.134.
+ : root : local,10.
+ : root : local,10.33.45.34
+ : root : local,10.33.45.34
+ : root : local
+ : root : local,10.

答案2

我的建议:使用 Perl。

perl-test包含 OP 中的数据的文件在哪里:

$ perl -pe 's/(?:(\s)192.*?(?:,|$))|(?:,192.*?(,|$))/$1$2/g' perl-test 
+ : root : local,10.
+ : root : local
+ : root : local,10.
+ : root : local,10.33.45.34
+ : root : local,10.33.45.34
+ : root : local
+ : root : local,10.

您可以轻松地将内容捕获并通过管道传输到perl -pe...

Perl 的正则表达式解析很类似于 sed,但功能更强大。

解释:

(?:)-- 在括号内容前面?:加上非捕获组。这样,仅用于分组的括号不会影响您在替换字符串中使用的反向引用$1和变量。$2

(\s)-- 捕获空格以用作替换字符串中的 $1。您想要匹配以空格开头的 192 IP 地址,以便您可以将其识别为列表的开头并保留其后的逗号。您仍然希望保留空格。

192.*?-- 非贪婪匹配。匹配到下一个逗号。Perl 中的默认行为(也是 sed 中的唯一行为)是匹配到最后一个逗号。这不是您想要的,并且您会看到列表中 IP 地址超过三个时的差异。

(?:,|$)-- 非捕获组告诉非贪婪匹配在第一个逗号或行末结束。

|——显然,替代下一个要匹配的正则表达式。

,?192.*?——非贪婪匹配 192,它不出现在列表的开头。

(,|$)-- 与之前一样,匹配 192 IP 地址后面的第一个逗号。在这种情况下,您确实想要捕获逗号。您想保留它,因为您用 删除了前面的逗号,并且,?192.*?列表中可能还有另一个项目跟在它后面。当然,如果列表中没有另一个项目跟在它后面,您将匹配行尾$。引用替换字符串中的引用$根本$2不会做任何事情;引用,将为您准备下一个列表项。所以无论哪种方式,您都得到了保障。

希望这有一定的意义!

相关内容