I have a XML file that looks something like this, and I only want to replace the last occurrence of /Shipment with /ShipHdr /ShipmentX:
我有一个看起来像这样的XML文件,我只想用/ ShipHdr / ShipmentX替换/ Shipment的最后一次出现:
<ShipmentX>
<ShipHdr>
<RefID>REF01</RefID>
<HeaderReferenceNumber>1234565</HeaderReferenceNumber>
<Shipment>
<RefCode>GHIJK</RefCode>
<ShipmentStatusCode>FG</ShipmentStatusCode>
</Shipment>
<Summary>
<TotalWeight>10</TotalWeight>
</Summary>
</Shipment>
Output:
输出:
<ShipmentX>
<ShipHdr>
<RefID>REF01</RefID>
<HeaderReferenceNumber>1234565</HeaderReferenceNumber>
<Shipment>
<RefCode>GHIJK</RefCode>
<ShipmentStatusCode>FG</ShipmentStatusCode>
</Shipment>
<Summary>
<TotalWeight>10</TotalWeight>
</Summary>
</ShipHdr>
</ShipmentX>
Any advice on how I can do this using perl or sed in a bash script?
关于如何使用perl或sed在bash脚本中执行此操作的任何建议?
Thanks!
谢谢!
2 个解决方案
#1
1
Using tac
and awk
:
使用tac和awk:
tac xml | awk '!p && /<\/Shipment>/{p=1;print "</ShipmentX>\n </ShipHdr>"; next} 1'| tac
<ShipmentX>
<ShipHdr>
<RefID>REF01</RefID>
<HeaderReferenceNumber>1234565</HeaderReferenceNumber>
<Shipment>
<RefCode>GHIJK</RefCode>
<ShipmentStatusCode>FG</ShipmentStatusCode>
</Shipment>
<Summary>
<TotalWeight>10</TotalWeight>
</Summary>
</ShipHdr>
</ShipmentX>
#2
0
In Perl the regex is $n =~ s/(?s).*\K<\/Shipment>/<\/ShipHdr> <\/ShipmentX>/;
在Perl中,正则表达式是$ n = ~s /(?s)。* \ K <\ / Shipment> / <\ / ShipHdr> <\ / ShipmentX> /;
Or, you can avoid the LTS with this syntax:
或者,您可以使用以下语法避免使用LTS:
$n =~ s{(?s).*\K</Shipment>}{</ShipHdr> </ShipmentX>};
$ n = ~s {(?s)。* \ K } { };
This regex finds only the last occurance of </Shipment>
, no matter what comes after it, ie. there won't be another </Shipment>
after it.
这个正则表达式只找到 的最后一次出现,无论后面是什么,即。它之后不会有另一个 。
#1
1
Using tac
and awk
:
使用tac和awk:
tac xml | awk '!p && /<\/Shipment>/{p=1;print "</ShipmentX>\n </ShipHdr>"; next} 1'| tac
<ShipmentX>
<ShipHdr>
<RefID>REF01</RefID>
<HeaderReferenceNumber>1234565</HeaderReferenceNumber>
<Shipment>
<RefCode>GHIJK</RefCode>
<ShipmentStatusCode>FG</ShipmentStatusCode>
</Shipment>
<Summary>
<TotalWeight>10</TotalWeight>
</Summary>
</ShipHdr>
</ShipmentX>
#2
0
In Perl the regex is $n =~ s/(?s).*\K<\/Shipment>/<\/ShipHdr> <\/ShipmentX>/;
在Perl中,正则表达式是$ n = ~s /(?s)。* \ K <\ / Shipment> / <\ / ShipHdr> <\ / ShipmentX> /;
Or, you can avoid the LTS with this syntax:
或者,您可以使用以下语法避免使用LTS:
$n =~ s{(?s).*\K</Shipment>}{</ShipHdr> </ShipmentX>};
$ n = ~s {(?s)。* \ K } { };
This regex finds only the last occurance of </Shipment>
, no matter what comes after it, ie. there won't be another </Shipment>
after it.
这个正则表达式只找到 的最后一次出现,无论后面是什么,即。它之后不会有另一个 。