数字替换时,Perl正则表达式替换

时间:2018-10-19 03:12:14

标签: regex perl

这可能真的很愚蠢,对于这种情况,我深表歉意。我不知道确切要搜索什么,过去半个小时左右的搜索工作也没有运气。无论如何...

因此,在构建过程中,我想使用perl自动化对xml的简单更改。这是我正在做的更改,它是名为mapred-site.xml

的配置文件的一部分
<property>
  <name>yarn.app.mapreduce.am.resource.mb</name>
-    <value>1024</value>
+    <value>4096</value>
</property>

在我将FOO更改为4096之前,我已经有一个Perl正则表达式替代品,完全可以满足我的需要。

cat mapred-site.xml | perl -p0e "s/(yarn.app.mapreduce.am.resource.mb<\/name>\s*?<value>)....(<\/value>)/\\1FOO\\2/s"

猜测问题是在\\1旁边紧跟着第一部分的数字,并且将它们拉进去并试图做\\14096或类似的东西,但是我没有能够提出解决方案。

如果命令本身草率/效率低下,我深表歉意,我仍然只是开始使用这些命令。

2 个答案:

答案 0 :(得分:2)

在正则表达式的右侧使用\1\2等大约已有一百万年的历史了;推荐的方法是使用$1$2等。如果使用它们,则可以使用花括号将变量名与任何相邻的东西(例如${1}FOO${2}(或好,${1}4096${2})。

答案 1 :(得分:0)

使用Mojo::DOM:这是一种不太脆弱/更易于维护的方式:

cat mapred-site.xml | perl -CSD -0777 -MMojo::DOM -pe '$_ = Mojo::DOM->new->xml(1)->parse($_); $_->find("property > name")->first(sub { $_->text eq "yarn.app.mapreduce.am.resource.mb" })->following("value")->first->content(4096)'

作为更具可读性的脚本:

use strict;
use warnings;
use Mojo::DOM;
use open ':std', ':encoding(UTF-8)';

my $dom = do { local $/; Mojo::DOM->new->xml(1)->parse(readline \*STDIN) };

my $name = $dom->find('property > name')
  ->first(sub { $_->text eq 'yarn.app.mapreduce.am.resource.mb' });
$name->following('value')->first->content(4096);

print $dom->to_string;