我正在创建一个 bash 脚本来设置 tomcat 服务器。我需要评论context.xml
文件中的一些内容。我尝试使用 sed 但无法匹配内容。
这是完整的context.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Context antiResourceLocking="false" privileged="true" >
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
我需要注释掉以下行:
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
这是我尝试用以下<Value......./>
内容替换的<!-- <Value........./> -->
sed '/^a test$/{$!{N;s/^<Valve className="org.apache.catalina.valves.RemoteAddrValve"\n\s.*allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" \/>/<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"\n allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" \/>-->/;ty;P;D;:y}}' context.xml
该命令运行时没有任何错误,但它没有更改原始文件中的任何内容。我想问题是因为新行和额外空间。我找到了新行的解决方案如何使用 sed 替换多行字符串?并添加\s*
跳过空格,但它仍然不起作用。我无法找到任何替代方案。
有什么简单的方法可以实现这一目标吗?或者我的命令有什么问题?
答案1
尝试:
sed '{$!{N;s/<Valve.*\n.*allow.* \/>/<!-- & -->/;ty;P;D;:y}}' content.xml
它输出:
...
<Context antiResourceLocking="false" privileged="true" >
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
如果需要,可以轻松修改以将注释标签放在单独的行上,即
sed '{$!{N;s/<Valve.*\n.*allow.* \/>/<!--\n&\n-->/;ty;P;D;:y}}' content.xml
答案2
尝试这个:
sed -r '/^\s*<Valve className\s*=\s*"org\.apache\.catalina\.valves\.RemoteAddrValve"\s*$/{h;z;N;s:^\n::;H;/^\s*allow\s*=\s*"127\\\.\\d\+\\\.\\d\+\\\.\\d\+\|::1\|0:0:0:0:0:0:0:1"\s*\/>\s*$/{g;s/.*/<!--\n&\n-->/}}' context.xml
输出:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Context antiResourceLocking="false" privileged="true" >
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
答案3
使用xsltproc
orxmlstarlet
与 XSL 转换一起transform.xsl
:
<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/|node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Context/Valve">
<xsl:text disable-output-escaping="yes"><!-- </xsl:text>
<xsl:copy-of select="."/>
<xsl:text disable-output-escaping="yes"> --></xsl:text>
</xsl:template>
</xsl:transform>
第一个模板只是身份转换,而第二个模板则在节点周围插入<!--
和。-->
/Context/Valve
如果您需要匹配节点中属性的精确值,请在match
第二个模板中使用更具体的 XPath 查询来执行此操作:
<xsl:template match="/Context/Valve[
@className='org.apache.catalina.valves.RemoteAddrValve' and
@allow='127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1'
]">
xmlstarlet tr transform.xsl file.xml
应用它可以通过或 with 来完成xsltproc transform.xsl file.xml
:
$ xsltproc transform.xsl file.xml
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Context antiResourceLocking="false" privileged="true">
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"/> -->
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
这将处理注释掉节点,无论它的格式是什么。
如果它是不会更改的静态文件,则只需在正确的行上插入注释标记即可:
sed '17s/^/<!-- /; 18s/$/ -->/' file.xml