-1

Have searched all over Stackoverflow and Google, and the closest answer:

sed -i -e 's|<element id="lastupdate">\([0-9]\{0,\}\)</element>|<element id="lastupdate">'"$(date -d @${contents})"'</element>|g' /var/www/html/index.html

works only when the tag's content is empty. If it is already changed, it can't be used anymore.

The idea is to change anything inside this tag id, and not only when it is empty.

Here's a good answer about reading anything inside a tag id, using awk: https://stackoverflow.com/a/13148004/5623661. But it works only for reading (with awk) and not for appending/replacing (using sed).

Another idea is to not only having a way to replace: but another to, alternatively, append into anything inside the given tag.

Is it possible to use a tool that works for HTML instead of one specific made for XML? Have tried:

Input: xmlstarlet ed --update '//element[@id="daipeg"]' --value 'new' index.html

Output:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Status - Floflis</title>
    <link rel="shortcut icon" href="icon.ico" type="image/x-icon"/>
    <link rel="icon" href="icon.ico" type="image/x-icon"/>
  </head>
  <body><h1>Floflis Status</h1><ul><li><p>Is DAI pegged to USD? <b><element id="daipeg">No</element></b></p></li><li><p>DAI now worth <b><element id="daiusd"/> USD</b></p></li></ul><p>Last updated in <element id="lastupdate"/> (updates every 5 minutes).</p><a href="https://floflis.github.io/" target="_blank">Main site</a> | <a href="https://floflis.github.io/blog" target="_blank">Blog</a> | <a href="https://floflis.github.io/docs" target="_blank">Documentation</a> | <a href="./api.html">DEV</a>
</body>
</html>

Desired result: changing the "No" inside <element id="daipeg">No</element> to "new", directly into the index.html file.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • 1
    Please take a look at [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – Cyrus Dec 01 '21 at 21:05
  • 1
    `sed` is the wrong tool. Please [Don't Parse XML/HTML With Regex.](https://stackoverflow.com/a/1732454/3776858). I suggest to use an XML/HTML parser (xmlstarlet, xmllint ...). – Cyrus Dec 01 '21 at 21:06
  • @Cyrus: yes, but they are poorly documented in an intuitive way (html-xml-utils, HXPIPE, xmlstarlet, xmllint). For example, tried this in `xmlstarlet`: `xmlstarlet ed --update '//element[@id="daipeg"]' --value 'new' index.html` and it only returned the html contents inside an XML tag (and didn't changed the contents of the desired element by id. Also, these are for XML, not HTML. – dani 'SO learn value newbies' Dec 01 '21 at 22:58
  • Please add sample input (no descriptions, no images, no links) and your desired output for that sample input to your question (no comment). – Cyrus Dec 01 '21 at 22:59

1 Answers1

1

(Responding to tag, I used version 1.6.1.)

If you fix a namespace issue and add an --inplace option you're there (replacing element value):

test "${bettersorrythansafe}" || cp file.xhtml file.xhtml.was
xmlstarlet ed --inplace -N X='http://www.w3.org/1999/xhtml' \
    --update '//X:element[@id="daipeg"]' --value 'new' file.xhtml

Or, with short options and a shortcut for the default namespace:

xmlstarlet ed -L -u '//_:element[@id="daipeg"]' -v 'new' file.xhtml

Note that the --inplace option is mentioned in xmlstarlet.txt but not in the user's guide. For more on the _ namespace shortcut see the user's guide ch. 5.

To append to the value, for example:

xmlstarlet ed -L -N X='http://www.w3.org/1999/xhtml' \
    --var peg '//X:element[@id="daipeg"]' \
    --var res "$((3 * 7 * 2))" \
    -u '$peg' -x 'concat($peg," and then ",$res)' file.xhtml
urznow
  • 1,576
  • 1
  • 4
  • 13