使用Perl和SED,Shell替换/替换不能按预期工作

时间:2014-07-30 14:52:30

标签: regex perl shell sed substitution

我有许多格式的字符串:

Sys!CTP_Live83000_@DRS_named_error_out_1
EServerJTP!CTP_Live56000_@input_error_queue_205

我试图删除" _number"即" _1"和" _205"从最后但我遇到了一些麻烦。

到目前为止,我已经提出了2个解决方案,这些解决方案都不像我喜欢的那样工作

1)使用Perl,它用空格替换字符串末尾的下划线和数字,但它也替换了字符串中所有出现的_。

...|/usr/bin/perl -pi -e 's/[_][0-9]*/ /g'

2)使用SED,这样可以保持字符串中的下划线完整,但只删除(用空格替换)字符串末尾的下划线和第一个数字,如果是2位和3位数,则保留一些数字:

...|sed 's/[_][0-9]/ /'

这是在Solaris 5.10服务器上。

我做错了什么?谢谢!

4 个答案:

答案 0 :(得分:2)

问题在于[0-9]*允许零个或多个数字,从而允许正则表达式匹配裸下划线_

要确保至少有一位数字,您可以使用+代替*

虽然/g选项在这里不合适,因为你只想替换一次出现的模式,如果你总是管道这个命令,-i perl选项是无关紧要的,所以这给出了< / p>

perl -pe 's/_[0-9]+/ /'

答案 1 :(得分:1)

假设您的输入位于file

sed -e 's/_[[:digit:]]\{1,\}$//' file 

将删除下划线,后跟每行末尾的一个或多个数字。请注意,_不需要自己的字符类[_]。这是POSIX兼容的,所以无论你的sed版本如何都应该工作。如果将输入传送到sed,它也应该同样有效。

在您的问题中使用[0-9]*的问题是或更多,因此任何下划线将匹配整个表达式并被删除。< / p>


看起来你的sed版本很老了!您可以使用[:digit:]获得更多成功,而不是使用POSIX字符类[0-9]

sed -e 's/_[0-9]\{1,\}//'

我还将锚点移到了行$的末尾,以防出现任何问题。

答案 2 :(得分:0)

sed 's/_[0-9][0-9]*$//'应该做的伎俩

输出结果为:

    Sys!CTP_Live83000_@DRS_named_error_out
    EServerJTP!CTP_Live56000_@input_error_queue

诀窍是使用美元符号强制它找到行尾。

答案 3 :(得分:0)

你可以:

sed 's/_[0-9]\+$//'

在行或模式(_)的末尾匹配下划线+和数字(一个或多个([0-9])数字$)。

当然你也可以使用一个字符列表:

sed 's/_[[:digit:]]\+$//'

启用-r后,无需引用+

sed -r 's/_[0-9]+$//'
sed -r 's/_[[:digit:]]+$//'

您还可以选择添加一个可以捕获额外尾随空格的额外模式:

sed -r 's/_[0-9]+[ \t\r]*$//'