Linux sed 正则表达式转义

Linux sed 正则表达式转义

我使用 sed -i 替换 xml 文件中的端口值,

<property name="port" value="8954" />

但我不知道如何转义正则表达式,我的正则表达式在下面。

(?<=name="port"\s+value=")\d+(?=")

我的命令是

sed -i "s/${PORTREX}/$NEWPORT/g" config.xml

答案1

我在评论中写下了这个,因为我没有意识到这已经是解决方案。 OP 写它有效,所以这次作为答案:

sed "s/\(name=\"port\" *value=\"\)[0-9]*/\1$NEWPORT/g" config.xml

OP 建议的正则表达式使用了一些非标准扩展,因此它不适用于sed,但您不需要它们:

我使用 sed -i 替换 xml 文件中的端口值,

但我不知道如何转义正则表达式,我的正则表达式在下面。

  • 您可以按原样使用该字符串,而不是“lookbehind” (?<=somestring),但它将\(somestring\)其标记为子表达式并在替换中重用它为\1,因此不要说“这需要在那里,但不能被替换”,只需替换它与它自己
  • 是(一次或多次出现)+的快捷方式\{1,\},但您也可以替换a+aa*。在这种情况下,使用 simple 可能会节省一些时间*,因为零出现是不可能的
  • 在我看来,阅读并不\d[0-9]
  • \s可以替换为[[:space:]][ <literal tab>]。这里一个简单的空格就可以完成工作

结论:几乎所有正则表达式扩展都可以轻松避免,可能会导致模式有点冗长或难以阅读,但通常没有缺点。一个例外是非贪婪匹配:在某些情况下,您需要一个没有它们的不同概念。

答案2

在 XML 文档上使用 XMLStarlet来更新属性为 的所有节点的file.xml属性值:valuepropertynameport

xmlstarlet ed -u '//property[@name="port"]/@value' -v "$NEWPORT" file.xml

XPATH 表达式的//property[@name="port"]/@value意思是“value属于任何属性为”property的节点的属性。所选属性将设置为(假定为端口号)。nameport$NEWPORT

例子:

$ NEWPORT=8080
$ xmlstarlet ed -u '//property[@name="port"]/@value' -v "$NEWPORT" file.xml
<?xml version="1.0"?>
<root>
  <property name="port" value="8080"/>
</root>

使用它sed来修改 XML 是很困难的,尤其是当您尝试使用sed根本不支持的类似 Perl 的正则表达式时。使用面向行的工具处理 XML 还充满了与换行符的放置以及行内节点属性的相对位置相关的潜在问题(请注意,<property name="port" value="8954" />与 相同<property value="8954" name="port" />)。字符串编码也是一个sed可以处理的潜在问题除非您在sed其内部进行了正确的解码(例如&amp;-->&等)

与使用正则表达式解析类 XML 数据的困难相关的问题:

答案3

尝试这个

sed -i "s/name=\"port\" value=\"8954\"/$NEWPORT/g" config.xml

相关内容