我一直在使用触发器操作符来替换输入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之外它还会掉落其他所有东西。
有没有办法可以用与上述类似的方式修改原始文件?
非常感谢, 饮酒
答案 0 :(得分:1)
这是我看到的任务的一种方法
perl -pe's{<d>VER\K.*?(</d>)}{xxx$1} if m{BLE} .. m{</d>}' data.txt
这取代了<d>VER
和(第一个)</d>
与xxx
之间的任何内容,在给定范围内的行上。 \K
是positive 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脚本中,您可以直接使用变量而不是上面的文字(VER
和xxx
)。
发布的代码中的问题不在&#34;触发器&#34; (range operator),它只选择行并正确使用。它与正则表达式一样,在最后一个数字之前有[A-Z]
,在它之后有另一个。数据在那里没有字母,所以它不匹配。
另请注意,\?
将quantifier ?
转换为文字?
,这也不在数据中。