GeoJeff
GeoJeff

Reputation: 13

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">

What I trying to do is a find and replace, where the string matches IgnoreAffinityRequests="true" AND Penguin-CL-Nest-s1 or s2, then when matched the string true should be replaced with false.

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

Here is the command I'm using on SLES11.3

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

Its does work with no regexp, any help gratefully appreciated, thanks.

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

Upvotes: 1

Views: 357

Answers (1)

Wintermute
Wintermute

Reputation: 44063

Editing XML with sed is not a good idea because whitespaces in unexpected places or reordered attributes -- that no one who works with XML expects to be a problem -- can break your script. XML is not a line-based format, sed is a line-based tool, so the two don't go well together.

Instead, I advise you to use a tool that parses and edits XML properly, such as xmlstarlet. In this case:

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

The key part of this is the XPath after -u, where

  • //ServerCluster is a ServerCluster node anywhere in the document,
  • //ServerCluster[condition]/@IgnoreAffinityRequests is the IgnoreAffinityRequests attribute of a ServerCluster node anywhere in the document that fulfills the condition, and
  • the condition (@Name="Penguin-CL-Nest-s1" or @Name="Penguin-CL-Nest-s2") and @IgnoreAffinityRequests="true" is true if the Name and IgnoreAffinityRequests attribute of the ServerCluster node fulfill it.

As such, the xmlstarlet command will update all entities that match this (i.e., the IgnoreAffinityRequests attributes of ServerClusterNodes whose IgnoreAffinityRequests attribute is currently true and whose Name attribute is either Penguin-CL-Nest-s1 or Penguin-CL-Nest-s2) with the value false.

Upvotes: 2

Related Questions