0

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.

EDIT2:

I found a perfect solution here: Sed regex change of file

Community
  • 1
  • 1
Akif
  • 398
  • 9
  • 22
  • Why -1? Feedback? – Akif Oct 10 '16 at 12:40
  • can you post entire expected output for clarity? there is no overlap to suggest any sort of issue, so add your attempt as well, so that you might learn where you went wrong.. and I too didn't downvote... – Sundeep Oct 10 '16 at 12:41
  • 1
    I didn't down vote but am wondering where is the expected output or the effort you put into it? – James Brown Oct 10 '16 at 12:41
  • @Sundeep and James Brown, I was kind of expecting this. That's why I have been trying for a couple of hours now. I did't add what I tried because it is too much to add. PS: I will edit my question to add the expected output. – Akif Oct 10 '16 at 12:47
  • 1
    @Akif, again, I don't get how is it too much to add.. show us one search and replacement sed command then.. – Sundeep Oct 10 '16 at 12:48
  • are you required to use only `sed`? – Ruslan Osmanov Oct 10 '16 at 13:14
  • @Sundeep I edited my question. I see there is some confusion because I was not completly clear. The way it was noted It seemed a very easy task. Is it clearer now? – Akif Oct 10 '16 at 13:14
  • @JamesBrown edited with expected output, should have done this right away. Thanks. – Akif Oct 10 '16 at 13:15
  • yes it is clear on expected output.. is your file input xml? you'd be better off using xml parser of some sort... the given sample input to expected output is easy to do with sed, but it won't likely handle if tags are multiple lines for instance, among other issues – Sundeep Oct 10 '16 at 13:16
  • see if this helps http://stackoverflow.com/questions/91791/grep-and-sed-equivalent-for-xml-command-line-processing – Sundeep Oct 10 '16 at 13:18
  • @Sundeep thanks but I rather don't install new utilities b/c of compatibility. And the rest of the my script uses sed with succes. It should be possible with SED right? With first occurance match maybee? – Akif Oct 10 '16 at 13:26
  • you need a parser! (And there are plenty of parsers for different languages, but not for Bash, AFAIK.) Otherwise, you'll have to implement the parser's job in `sed`. – Ruslan Osmanov Oct 10 '16 at 13:52

1 Answers1

1

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>
heemayl
  • 39,294
  • 7
  • 70
  • 76