Akif Akif - 1 month ago 13
Linux Question

Find and replace string in bash script with SED

I know I can do this with SED. But in my specific task it is kind of complex. So I couldn't figure it out despite the many examples across this site.

I have a configuration file with credentials.

<username><![CDATA[prefix_cms]]></username>
<password><![CDATA[complexpwd]]></password>
<dbname><![CDATA[prefix_cms]]></dbname>


I want to change all credentials to a new unique value. This is a problem when I use find an replace with SED because it changes the username AND the dbname to its new value.

The new values should be for instance:

newusername
newpassword
newdbname


How would I do this? I have looked for first occurence in SED but couldn't get it working for some reason.

I have also tried to find and replace the whole line including the XML and CDATA protions, but this makes it more complex because of the spcial characters.

How can I solve this?

EDIT:

The output I am looking for.

<username><![CDATA[newusername]]></username>
<password><![CDATA[newpassword]]></password>
<dbname><![CDATA[newdbname]]></dbname>


Looking for the first answer I see I have not been very clear about what I wanted.

Answer

Do:

sed -E 's/username|password|dbname/new&/g' file
  • username|password|dbname matches any of username, password, dbname

  • in the replacement, new is perpended before each match (&), and is done on all occurrences of a match in a line (g)

Example:

% cat file.txt
<username><![CDATA[prefix_cms]]></username>
<password><![CDATA[complexpwd]]></password>
<dbname><![CDATA[prefix_cms]]></dbname>

% sed -E 's/username|password|dbname/new&/g' file.txt
<newusername><![CDATA[prefix_cms]]></newusername>
<newpassword><![CDATA[complexpwd]]></newpassword>
<newdbname><![CDATA[prefix_cms]]></newdbname>

Answer to the edited question:

sed -E 's/^(<([^>]+).*\[)[^]]+(.*)/\1new\2\3/' file

Example:

% cat file.txt
<username><![CDATA[prefix_cms]]></username>
<password><![CDATA[complexpwd]]></password>
<dbname><![CDATA[prefix_cms]]></dbname>

% sed -E 's/^(<([^>]+).*\[)[^]]+(.*)/\1new\2\3/' file.txt
<username><![CDATA[newusername]]></username>
<password><![CDATA[newpassword]]></password>
<dbname><![CDATA[newdbname]]></dbname>