0

I want to find and replace the VALUE into a xml file :

<test name="NAME" value="VALUE"/>

I have to filter by name (because there are lot of lines like that).

Is it possible ?

Thanks for you help.

5
  • did you want to replace VALUE with? Commented Jul 2, 2014 at 13:00
  • sed -i 's~VALUE~foo~g' file.xml Commented Jul 2, 2014 at 13:01
  • Value is a random value, for example I set VALUE, but it's a string, and must be replace by an other string. Commented Jul 2, 2014 at 13:06
  • so it would be after the value= field. Commented Jul 2, 2014 at 13:07
  • Yes, and I have to filter by name. Commented Jul 2, 2014 at 13:09

2 Answers 2

1

Since you tagged the question "bash", I assume that you're not trying to use an XML library (although I think an XML expert might be able to give you something like an XSLT processor command that solves this question very robustly), but that you're simply interested in doing search & replace from the commandline.

I am using perl for this:

perl -pi -e 's#VALUE#replacement#g' *.xml

See perlrun man page: Very shortly put, the -p switches perl into text processing mode, -i stands for "in-place", and -e let's you specify an expression to apply to all lines of input.

Also note (if you are not too familiar with that already) that you may use other characters than # (common ones are %, a comma, etc.) that don't clash with your search & replacement strings.

There is one small caveat: perl will read & write all files given on the commandline, even those that did not change. Thus, the files' modification times will be updated even if they did not change. (I usually work around that with some more shell magic, e.g. using grep -l or grin -l to select files for perl to work on.)

EDIT: If I understand your comments correctly, you also need help with the regular expression to apply. Let me briefly suggest something like this then:

perl -pi -e 's,(name="NAME" value=)"[^"]*",\1"NEWVALUE",g' *.xml
Sign up to request clarification or add additional context in comments.

6 Comments

I don't know the VALUE, it's a string, replaced in my post by "VALUE". And, I have to filter by name.
If you know that name= always comes before value=, it is just a matter of extending the regular expression in the above command. If you don't, I would tag the question with "xml" and use a proper XML tool for the job.
Yes name comes always before value ;)
OK, I have updated my answer, also using \1 in order not to repeat too much of the search string in the replacement string. Hope that helps, even though I feel uncomfortable about mangling non-trivial XML using just string processing. ;-)
Great, this is perfect.
|
1

Related: bash XHTML parsing using xpath

You can use SED:

SED 's/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/' test.xml

where test.xml is the xml document containing the given node. This is very fragile, and you can work to make it more flexible if you need to do this substitution multiple times. For instance, the current statement is case sensitive, so it won't substitute the value on a node with the name="name", but you can add a case insensitivity flag to the end of the statement, like so:

('s/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/I').

Another option would be to use XSLT, but it would require you to download an external library. It's pretty versatile, and could be a viable option for more complex modifications to an XML document.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.