如何使用sed跳过第一个匹配项后替换第一个匹配项

时间:2018-07-10 20:30:55

标签: bash shell unix sed

假设我有以下一段文字:

<Data>
    <Country>
       <Name>Portugal<\Name>
       <Population>10M</Population>
       <Sub>
          <Code>Y</Code>
       </Sub>
    </Country>
    <Country>
       <Name>Spain<\Name>
       <Population>30M</Population>
       <Sub>
          <Code>Y</Code>
       </Sub>
    </Country>
</Data>

如何在不替换其余国家/地区代码的情况下将葡萄牙国家的Y替换为N

我尝试使用sed:

sed -i '/<Country>Portugal<\/Country>/{s/Y/N/;}' file.xml

但这不能替代任何东西。

您能告诉我我做错了什么吗?匹配葡萄牙后,如何替换第一次出现的Y

谢谢!

4 个答案:

答案 0 :(得分:2)

避免使用parsing XML with regex。使用类似xmlstarlet的XML处理工具:

$ cat foo.xml
<Data>
  <Country>
    <Name>Portugal</Name>
    <Population>10M</Population>
    <Sub>
      <Code>Y</Code>
    </Sub>
  </Country>
  <Country>
    <Name>Spain</Name>
    <Population>30M</Population>
    <Sub>
      <Code>Y</Code>
    </Sub>
  </Country>
</Data>

$ xmlstarlet edit --update '/Data/Country[Name="Portugal"]/Sub/Code' -v "N" foo.xml
<?xml version="1.0"?>
<Data>
  <Country>
    <Name>Portugal</Name>
    <Population>10M</Population>
    <Sub>
      <Code>N</Code> 
    </Sub>
  </Country>
  <Country>
    <Name>Spain</Name>
    <Population>30M</Population>
    <Sub>
      <Code>Y</Code>
    </Sub>
  </Country>
</Data>

答案 1 :(得分:0)

使用范围匹配。

sed '/<Name>Portugal</,/<\/Country>/ s/<Code>Y</<Code>N</' file.xml

(已编辑,以匹配更新的要求。)

答案 2 :(得分:0)

这可能对您有用(GNU sed):

sed '/<Country>/{:a;N;/<\/Country>/!ba;/Portugal/s/Y/N/}' /file

收集Country的行,然后匹配这些行以包含Portugal,并用Y替换第一个N

答案 3 :(得分:0)

如果您输入的内容实际上始终是该格式,那么您所需要做的就是:

$ awk '/<Name>/{f=/Portugal/} f && /<Code>/{sub(/Y/,"N")} 1' file
<Data>
    <Country>
       <Name>Portugal<\Name>
       <Population>10M</Population>
       <Sub>
          <Code>N</Code>
       </Sub>
    </Country>
    <Country>
       <Name>Spain<\Name>
       <Population>30M</Population>
       <Sub>
          <Code>Y</Code>
       </Sub>
    </Country>
</Data>
相关问题