带有 AND 运算符的 Sed 正则表达式不起作用,为什么不呢?

Sed reg expression with an AND operator, does not work, why not?

<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="Penguin-CL-Nest-s1" ServerIOTimeoutRetry="-1">

我想做的是查找和替换,其中字符串匹配 IgnoreAffinityRequests="true" AND Penguin-CL-Nest-s1 或 s2,然后在匹配时应将字符串 true 替换为 false。

enterIgnoreAffinityRequests="true"
Name="Penguin-CL-Nest-s1"
Name="Penguin-CL-Nest-s2"

这是我在 SLES11.3 上使用的命令

sed -i -r -e '/IgnoreAffinityRequests="true"/{;/Name="Penguin-CL-Nest-\w\d"/s/IgnoreAffinityRequests="true"/IgnoreAffinityRequests="false"/;}' example1

它确实可以在没有正则表达式的情况下工作,非常感谢任何帮助,谢谢。

sed -i -e '/IgnoreAffinityRequests="true"/{;/Name="Penguin-CL-Nest-s1"/s/IgnoreAffinityRequests="true"/IgnoreAffinityRequests="false"/;}' example1

使用 sed 编辑 XML 不是一个好主意,因为意外位置的空格或重新排序的属性——使用 XML 的人都不会认为这是一个问题——可能会破坏你的脚本. XML 不是基于行的格式,sed 是基于行的工具,所以两者不能很好地结合在一起。

相反,我建议您使用能够正确解析和编辑 XML 的工具,例如 xmlstarlet。在这种情况下:

xmlstarlet ed -u '//ServerCluster[(@Name="Penguin-CL-Nest-s1" or @Name="Penguin-CL-Nest-s2") and @IgnoreAffinityRequests="true"]/@IgnoreAffinityRequests' -v 'false'

这里的关键部分是 -u 之后的 XPath,其中

  • //ServerCluster 是文档中任意位置的 ServerCluster 节点,
  • //ServerCluster[condition]/@IgnoreAffinityRequests 是文档中满足 condition
  • ServerCluster 节点的 IgnoreAffinityRequests 属性
  • 如果 ServerCluster 节点的 NameIgnoreAffinityRequests 属性满足条件 (@Name="Penguin-CL-Nest-s1" or @Name="Penguin-CL-Nest-s2") and @IgnoreAffinityRequests="true" 则为真。

因此,xmlstarlet 命令将更新所有与此匹配的实体(即 ServerClusterNodesIgnoreAffinityRequests 属性,其 IgnoreAffinityRequests 属性当前为真且其Name 属性是 Penguin-CL-Nest-s1Penguin-CL-Nest-s2),值为 false.