shell 在最后一个匹配模式之前和之后,如果存在注解,则删除注解,如果不存在注解,则添加注解

utugiqy6  于 2023-06-06  发布在  Shell
关注(0)|答案(1)|浏览(184)

我有一个xml文件,其中包含的行类型-

<!--
    <xml:tag.type-one>on</xml:tag.type-one>
    <xml:tag.type-two>off</xml:tag.type-two>
    -->

1.我想删除注解**,如果它们已经存在**(如上所述)在<xml:tag.type-one>on</xml:tag.type-one>之前和<xml:tag.type-two>off</xml:tag.type-two>之后。如果这些标签已经没有注解,则不需要进行任何更改。
1.我想在<xml:tag.type-one>on</xml:tag.type-one>之前和<xml:tag.type-two>off</xml:tag.type-two>之后添加注解**(如果它们还没有出现)。如果这些标签已经被注解,那么不需要进行任何更改。
我一直在努力-

sed -ni '/^\s*<xml:tag.type-one>on<\/xml:tag.type-one>\s*$/{x;d;};1h;1!{x;p;};${x;p;}' path/to/file 
sed -i '/^\s*<xml:tag.type-two>off<\/xml:tag.type-two>\s*$/{N;s/\n.*//;}' path/to/file

这些命令会删除该行前后的(<!---->注解)(如果存在)。如果不匹配,这些命令将删除匹配模式前后的行。
如何删除匹配模式前后的<!---->(仅当它们存在时)。另外,如何仅在匹配模式的最后一次出现时进行此更改?

ergxz8rk

ergxz8rk1#

假设整个xml数据可以轻松地放入内存中:

  • 选择输入中不存在的字符串用作标记
  • 搜索所需行并插入标记
  • 当注解标记出现在下一个标记时,删除这两个标记
  • 用注解标记替换剩余的标记
# these are regex - escape shell and sed metacharacters
v1='<xml:tag.type-one>on<\/xml:tag.type-one>'
v2='<xml:tag.type-two>off<\/xml:tag.type-two>'
m1='\x00\x01'
m2='\x00\x02'

sed -zE "
    s/[ \t]*$v1\s*$v2[ \t]*\n/$m1&$m2/g
    s/[ \t]*<\!--\s*$m1|$m2\s*-->[ \t]*\n//g
    s/$m1([ \t]*)/\1<\!--\n\1/g
    s/([ \t]*)([^\n]+\n)$m2/\1\2\1-->\n/g
" /path/to/file

要只更改最后一个匹配项,请使用贪婪匹配来消耗前面的所有行:

sed -zE "
  s/(.*\n)?([ \t]*$v1\s*$v2[ \t]*\n)/\1$m1\2$m2/
  s/[ \t]*<\!--\s*$m1|$m2\s*-->[ \t]*\n//g
  s/$m1([ \t]*)/\1<\!--\n\1/g
  s/([ \t]*)([^\n]+\n)$m2/\1\2\1-->\n/g
" /path/to/file

相关问题