处理触发器操作员的输出

时间:2017-03-14 19:22:55

标签: regex perl shell

我一直在使用触发器操作符来替换输入xml文件中的特定值。

文件结构如下:

$( 'form' ).on({
    submit: function() {
         return false;
    }
});

所以我想说我想要更改任何特定变量的版本字段(d和c)。为了简洁起见,让它成为BLE。我必须首先找到具有BLE值的块(第1-7行),然后用新值替换字段。

我一直在尝试不同的东西,比如:

<a>BLE</a>
<-- hur dur -->
<b>12345</b>
<-- hur der -->
<c>VER1.2.3</c>
<-- hur dest -->
<d>VER1.2.3</d>

<a>CLE</a>
<-- hur dur -->
<b>12345</b>
<-- hur der -->
<c>VERX'.Y'.Z'</c>
<-- hur dest -->
<d>VERX'.Y'.Z'</d>

<a>DLE</a>
<-- hur dur -->
<b>12345</b>
<-- hur der -->
<c>VERX".Y".Z"</c>
<-- hur dest -->
<d>VERX".Y".Z"</d>
etc ...

perl -pi.bak -ne 'if ( /BLE/ .. /<\/d/ ){ s/VER[[:digit:]]\+\.[[:digit:]]\+\.[A-Z][[:digit:]]\+[A-Z]\?/$ver/}' dur.xml

其中$ ver是一个set变量(ver =&#34; VERX.Y.Z&#34;)。然而,第一个对输入文件没有任何作用(我更喜欢在原地进行);第二个产生或多或少产生我想要但输出仅限于BLE块:

perl -ne "print if ( /BLE/ .. /<\/d>/ ) " dur.xml | sed "/VER[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+[A-Z]\?/$ver/"

但是这个输出不能轻易地重定向到带有&gt;的文件。因为除了BLE之外它还会掉落其他所有东西。

有没有办法可以用与上述类似的方式修改原始文件?

非常感谢, 饮酒

1 个答案:

答案 0 :(得分:1)

这是我看到的任务的一种方法

perl -pe's{<d>VER\K.*?(</d>)}{xxx$1} if m{BLE} .. m{</d>}' data.txt

这取代了<d>VER和(第一个)</d>xxx之间的任何内容,在给定范围内的行上。 \Kpositive lookbehind的形式,它会丢弃之前的匹配项,因此我们不必捕获它们并将它们放回去。

-p每次打印$_s{}{}更改它,因此您可以打印,更改或不更改所有行。它没有任何目的同时具有-n(相同但不打印),但如果你这样做,那么-p会覆盖另一个。要使用备份更改就地文件确实添加-i.bak。见perlrun

如果您需要访问特定号码,则可以使用正则表达式

s{<d>VER\K(\d+)\.(\d+)\.(\d+)</d>}{$1.$new.$3</d>}

为了允许在数字后跟一个可选字母,代码提示,请使用(\d+[A-Z]?)。如果'"中的X'X"是实际字符,请调整此项(第一个示例很好)。如果您打算将它们用作&#34; X-prime&#34; (和双重素数),不要 - 这里有误导性。

为了更灵活地将其转换为脚本,无论如何这可能都是个好主意。如果这是在shell脚本中,您可以直接使用变量而不是上面的文字(VERxxx)。

发布的代码中的问题不在&#34;触发器&#34; (range operator),它只选择行并正确使用。它与正则表达式一样,在最后一个数字之前有[A-Z],在它之后有另一个。数据在那里没有字母,所以它不匹配。

另请注意,\?quantifier ?转换为文字?,这也不在数据中。