我已经很久没有在这里发过问题了。需要一些帮助才能让我的 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
不会做任何事情;引用,
将为您准备下一个列表项。所以无论哪种方式,您都得到了保障。
希望这有一定的意义!