Perl multiline替换为空格/使用正则表达式

时间:2014-12-20 19:57:00

标签: regex perl

我正在尝试替换

 <!--
    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>/put/your/solr/home/here</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
  -->
从shell脚本

。因此我尝试使用命令

来使用perl
sudo perl -0777 -i -pe 's:<!--\n *<env-entry>\n *<env-entry-name>solr/home</env-entry-name>\n *<env-entry-value>/put/your/solr/home/here</env-entry-value>\n *<env-entry-type>java.lang.String</env-entry-type>\n *</env-entry>\n *-->:<env-entry>\n <env-entry-name>solr/home</env-entry-name>\n <env-entry-value>/home/solr</env-entry-value>\n <env-entry-type>java.lang.String</env-entry-type>\n </env-entry>:g' /usr/share/tomcat6/webapps/solr/WEB-INF/web.xml

根据this regex test page它应该可以工作,但由于某种原因,从终端调用命令不起作用。

修改

sudo perl -0777 -i -pe 's:<!--\n 
 *<env-entry>\n 
 *<env-entry-name>solr/home</env-entry-name>\n 
 *<env-entry-value>/put/your/solr/home/here</env-entry-value>\n 
 *<env-entry-type>java.lang.String</env-entry-type>\n 
 *</env-entry>\n 
 *-->:
 <env-entry>\n 
 <env-entry-name>solr/home</env-entry-name>\n 
 <env-entry-value>/home/solr</env-entry-value>\n 
 <env-entry-type>java.lang.String</env-entry-type>\n 
 </env-entry>:g' /usr/share/tomcat6/webapps/solr/WEB-INF/web.xml

2 个答案:

答案 0 :(得分:4)

给定一个名为data的数据文件:

blah blah blah
 <!--
    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>/put/your/solr/home/here</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
  -->
blah blah more blah

和包含以下内容的shell脚本xx.sh

perl -0777 -pe 's:<!--\n 
\s*<env-entry>\n 
\s*<env-entry-name>solr/home</env-entry-name>\n 
\s*<env-entry-value>/put/your/solr/home/here</env-entry-value>\n 
\s*<env-entry-type>java.lang.String</env-entry-type>\n 
\s*</env-entry>\n 
\s*-->:
 <env-entry>
     <env-entry-name>solr/home</env-entry-name>
         <env-entry-value>/home/solr</env-entry-value>
     <env-entry-type>java.lang.String</env-entry-type>
 </env-entry>
:gx' "$@"

运行bash xx.sh data的输出是:

blah blah blah

 <env-entry>
     <env-entry-name>solr/home</env-entry-name>
         <env-entry-value>/home/solr</env-entry-value>
     <env-entry-type>java.lang.String</env-entry-type>
 </env-entry>

blah blah more blah

脚本中的主要更改是:

  1. 删除sudo;正如已经指出的那样,我认为将未经测试的代码作为root运行是非常不安全的,即使在备份的虚拟化开发环境中也是如此。有一天发生错误并且发现您这次没有处于备份的虚拟化环境中存在太大的危险。你需要非常谨慎。

  2. 删除-i,以便在知道脚本工作之前不会修改文件。

  3. 将最重要的x限定符添加到正则表达式中;这意味着它使用扩展格式,其中空格不重要。

  4. 由于x限定符,空格匹配从*(空白星)变为\s*

  5. 我复制和粘贴的内容在替换文本行中有尾随空白,因此\n后面跟着一个空格,有效地位于下一行的开头。我还将文本缩进了一点(<env-entry-value>行),因此很容易看出正则表达式是有效的。


  6.   

    但是,不幸的是,如果我用我的文件尝试这个,它不起作用。如果我将文件中的部分复制/粘贴到数据文件的内容下方,则会显示like this。我找不到任何区别,但执行shell脚本只会替换最顶层的脚本。

    检查文件后,使用来自Pastebin的copy'n'paste,导致失败的<!--后面有一个空白。需要修改匹配的正则表达式来处理它。我这样做的方法是在行尾用非贪婪的空格匹配(\s*?):

    perl -0777 -pe 's:<!--\s*?\n 
    \s*<env-entry>\s*?\n 
    \s*<env-entry-name>solr/home</env-entry-name>\s*?\n 
    \s*<env-entry-value>/put/your/solr/home/here</env-entry-value>\s*?\n 
    \s*<env-entry-type>java.lang.String</env-entry-type>\s*?\n 
    \s*</env-entry>\s*?\n 
    \s*-->:
     <env-entry>
         <env-entry-name>solr/home</env-entry-name>
             <env-entry-value>/home/solr</env-entry-value>
         <env-entry-type>java.lang.String</env-entry-type>
     </env-entry>
    :gx' "$@"
    

    我添加了各种各样的空格(但没有打扰测试标签或流浪换行等)到最后,一切似乎都运行正常。我可以说“我讨厌尾随空格”。并且,在我的书中,值得花时间确保文件没有尾随空格 - 它们会引起混淆(我称此问题为起诉的证人)。电子邮件签名前面是dash-dash-blank-CRLF(或dash-dash-blank-LF);我讨厌这个。但是,我无法轻易修复标准。

答案 1 :(得分:0)

$ cat pattern.txt 
<!--
    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>/put/your/solr/home/here</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
-->

$ cat replace.txt
<!--
    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>/home/solr</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
-->

$ perl -0777pe '$pattern=`cat pattern.txt`; s/\Q$pattern\E/`cat replace.txt`/e' -i /usr/share/tomcat6/webapps/solr/WEB-INF/web.xml