我有一个文件,我试图使用来自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地址的一部分。
我似乎无法弄清楚我做错了什么,并希望得到一些帮助。
提前致谢。
答案 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
。 -
和@
并不特别,所以没有必要逃避它们,尽管它们并没有什么不妥。