I have a XML file, that I'm trying to edit inplace using sed
on a mac
Sample XML:
...
<clientSSLCertificatesConfiguration>
<certificates>
<clientCertificate>
<certificate>
<name>1234567</name>
<storeAlias>cert_alias</storeAlias>
</certificate>
</clientCertificate>
</certificates>
</clientSSLCertificatesConfiguration>
...
I'm trying to replace everything between <certificates> .. </certificates>
using sed
.
My replacement block is stored in a variable called $CERT_UPDATE
looks like this:
<certificates>
<clientCertificate>
<certificate>
<name>new_cert_name</name>
<storeAlias>new_alias</storeAlias>
</certificate>
</clientCertificate>
</certificates>
So far, I've the following piece
sed -i -ne "/<certificates>/,/<\/certificates>/ {
/<\/certificates>/ s@.*@$CERT_UPDATE@
t
d
}" my_file.xml
There are some issues in my script:
(1) The new line are not preserved in the file after replacement
(2) Rerunning the script deletes everything after </certificates>
(3) Running on online GNU sed
tool works without error. However, running this on a mac I get sed: 2: "/<certificates>/,/<\/ce ...": unescaped newline inside substitute pattern
error
CodePudding user response:
You can try this approach if your shell supports process substitution:
sed -i.backup -n '
/^[[:blank:]]*<certificates>/,/^[[:blank:]]*<\/certificates>/!{p;d;}
/^[[:blank:]]*<\/certificates>/!d
r '<(echo "$CERT_UPDATE") my_file.xml
Otherwise, you can write the contents of the variable CERT_UPDATE
to a temporary file and replace the <(echo "$CERT_UPDATE")
with the name of that temporary file.
CodePudding user response:
To modify the 2 fields with a dedicated XML tool such as xmlstarlet you can say,
test "${bettersorrythansafe}" || cp file.xml file.xml.was
xmlstarlet edit --inplace --omit-decl \
--var T '//clientCertificate/certificate[name = "1234567"]' \
-u '$T/name' -v 'new_cert_name' \
-u '$T/storeAlias' -v 'new_alias' \
file.xml
... assuming namespaces agree.