【问题标题】:Replace string in shell using sed or Perl?使用 sed 或 Perl 替换 shell 中的字符串?
【发布时间】:2015-11-18 10:21:43
【问题描述】:

如何替换以下字符串:

<value>-myValue</value>
          <value>1234</value>

让它成为:

<value>-myValue</value>
          <value>0</value>

请注意有换行符。

【问题讨论】:

  • 您想知道一般的字符串替换还是replacement across multiple lines
  • 是 1234 还是仅仅代表一个数字字符串?替换总是为零吗?你试过什么?
  • 关于多行替换。我试过 sed '/-myValue.*/ {N; s/-myValue.*\./-myValue.*value>0}' 文件名
  • 如果这确实是 XML,sed 不是处理它的好工具。考虑使用 xmlstarlet,例如xmlstarlet ed -u '//value[.="-myValue"]/following-sibling::value[1]' -v 0 filename.xml

标签: perl shell replace sed


【解决方案1】:

如果这是 XML,TLP 是正确的,即 XML 解析器会更好。但是,继续使用您的 sed 方法,请考虑:

$ sed '/<value>-myValue/ {N; s/<value>[[:digit:]]\+/<value>0/}' file
<value>-myValue</value>
          <value>0</value>

【讨论】:

    【解决方案2】:

    脚本

    sed -e '/<value>-myValue</,/<value>/{ /<value>[0-9][0-9]*</ s/[0-9][0-9]*/0/; }' data
    

    从包含&lt;value&gt;-myValue&lt; 的行到包含&lt;value&gt; 的下一行,如果该行与&lt;value&gt;XX&lt; 匹配,其中XX 是一个或多个数字的字符串,请将数字字符串替换为0

    输入

    This is not something to change
    <value>-myValue</value>
              <value>1234</value>
    <value>myValue</value>
              <value>1234</value>
    nonsense
    <value>-myValue</value>
              <value>abcd</value>
    <value>-myValue</value>
              <value>4321</value>
    stuffing
    

    输出

    This is not something to change
    <value>-myValue</value>
              <value>0</value>
    <value>myValue</value>
              <value>1234</value>
    nonsense
    <value>-myValue</value>
              <value>abcd</value>
    <value>-myValue</value>
              <value>0</value>
    stuffing
    

    【讨论】:

      【解决方案3】:

      您可以稍微简化一下,具体取决于您具体要使用的标准:

      #!/usr/bin/env perl
      use strict;
      use warnings;
      use XML::Twig;
      
      my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' )->parse( \*DATA );
      foreach my $value ( $twig->findnodes('//value') ) {
          if (    $value->trimmed_text eq '-myValue'
              and $value->next_sibling('value')
              and $value->next_sibling('value')->text =~ m/^\d+$/ )
          {
              $value->next_sibling('value')->set_text('1234');
      
          }
      }
      
      $twig->print;
      
      __DATA__
      <root>
      <value>-myValue</value>
                <value>0</value>
                </root>
      

      这个输出:

      <root>
        <value>-myValue</value>
        <value>1234</value>
      </root>
      
      • 它会解析您的 XML。
      • 查找标签为value 的所有节点。
      • 检查它是否有兄弟姐妹。
      • 检查兄弟是“只是数字”,例如匹配正则表达式^\d+$
      • 将该兄弟的内容替换为1234

      并且无论格式如何,都可以在 XML 上工作,这是 XML 的问题 - 从根本上讲,您可以做很多完全有效的事情,这些事情在 XML 中的语义相同。

      【讨论】:

        猜你喜欢
        • 2021-09-28
        • 1970-01-01
        • 2014-10-19
        • 2021-03-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-15
        • 2012-10-15
        • 2017-11-17
        相关资源
        最近更新 更多