命令行perl的奇怪行为

时间:2012-03-20 21:02:24

标签: regex perl shell

我有一个文件,我试图使用来自Ubuntu Linux(Natty)终端的perl进行修改。

文件的名称是vm.args,前两行如下:

## Name of the riak node
-name riak@127.0.0.1

我正在尝试使用perl来更新IP地址。以下是我的代码:

riak_ip=`ifconfig eth1 | grep "inet addr" | cut -d ":" -f2 | cut -d " " -f1`
perl -0777 -i -pe "s/(\-name[\t ]*riak\@)[^\n]+/\1$riak_ip/g" vm.args

我们假设我得到的IP地址是10.181.106.32。 perl命令给了我一个我无法理解的结果。在终端中运行上面的文件后,我的文件中的前两行变为:

## Name of the riak node
H.181.106.32

字母H和IP地址的一部分。

我似乎无法弄清楚我做错了什么,并希望得到一些帮助。

提前致谢。

5 个答案:

答案 0 :(得分:2)

这似乎可靠地运作:

perl -0777 -i -pe "s/(-name\\s*riak@).*/\${1}$riak_ip/g" vm.args

\\1$riak_ip”似乎会导致一些问题,因为如果\1172.20.2.136为172.20.2.136,perl会将其视为“$riak_ip”。我的猜测是后面引用“1172”引起了一些奇怪。无论如何,切换到${1}形式消除了误解的可能性(双关语)。

答案 1 :(得分:1)

这真的应该在Perl中完成,它比从shell脚本更好地从文本中提取数据。这样的东西应该有效,但我目前无法测试它。

perl -0777 -i -pe '($ip)=`ifconfig eth1`=~/inet addr:([\d.]+)/;s/-name\s+riak@\K[\d.]+/$ip/g;' vm.args

如果有人能确认这是否正常,我将不胜感激。请注意Perl正则表达式中的\K构造是最近添加的,可能不在任何给定的Perl安装中。

答案 2 :(得分:0)

问题是\1与第一个IP八位字节连接在一起。为了使其尽管连接起作用,需要使用${1}语法并正确引用。这有效:

perl -0777 -i -pe "s/(\-name[\t ]*riak\@)[^\n]+/\${1}$riak_ip/g" vm.args

您可以考虑对正则表达式部分使用单引号,以删除一层引用:

perl -0777 -i -pe 's/(-name[\t ]*riak@)[^\n]+/${1}'"$riak_ip"'/g' vm.args

(根据评论编辑/更正,我之前的建议是错误的。)

答案 3 :(得分:0)

\K序列(v5.10)很有用。 [^\n]实际上是.,除非使用/s修饰符。除非您打算多次替换字符串,否则无需/g选项。

perl -0777 -i -pe "s/\-name[\t ]*riak\@\K.+/$riak_ip/" vm.args

答案 4 :(得分:-1)

这将是正确的正则表达式:

perl -0777 -i -pe "s/(-name\s*riak@)\S+/$1$riak_ip/g" vm.args

结果:

## Name of the riak node
10.181.106.32

使用\s表示空格字符,使用\S(无空格字符)匹配整个IP地址。在替换字符串中,使用$1代替\1-@并不特别,所以没有必要逃避它们,尽管它们并没有什么不妥。