Linux bash脚本 - 替换文件中最后一次出现的字符串

时间:2015-06-05 22:20:16

标签: regex linux bash perl sed

我有一个看起来像这样的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>

输出:

<ShipmentX>
  <ShipHdr>
   <RefID>REF01</RefID>
   <HeaderReferenceNumber>1234565</HeaderReferenceNumber>
   <Shipment>
     <RefCode>GHIJK</RefCode>
     <ShipmentStatusCode>FG</ShipmentStatusCode>
   </Shipment>
   <Summary>
     <TotalWeight>10</TotalWeight>
   </Summary>
  </ShipHdr>
</ShipmentX>

关于如何在bash脚本中使用perl或sed执行此操作的任何建议?

谢谢!

2 个答案:

答案 0 :(得分:1)

使用tacawk

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>

答案 1 :(得分:0)

在Perl中,正则表达式是$n =~ s/(?s).*\K<\/Shipment>/<\/ShipHdr> <\/ShipmentX>/;

或者,您可以使用以下语法避免使用LTS:

$n =~ s{(?s).*\K</Shipment>}{</ShipHdr> </ShipmentX>};

这个正则表达式只找到</Shipment> last 出现,无论后面是什么,即。在它之后不会再成为</Shipment>