1

I have an xml file with content following this format:

<type:color>000000</type:color>
<type:color>FFFFFF</type:color>

The information within the tags are hex colors (many different colors), but they need to begin with a pound sign (#) to work in a particular application, ie:

<type:color>#000000</type:color>
<type:color>#FFFFFF</type:color> 

How can I use sed to append the pound symbol in this file? Using sed 4.8 BTW, thanks!

2
  • 3
    Please edit your post to include what you've tried, and how it didn't do what you expected. Your example is rather trivial, and should be an excellent test case for someone learning how to use sed for the first time. When starting out, be sure to experiment on a copy of your actual file, so that you won't be worried about damaging any data.
    – Jim L.
    Commented Jul 8 at 18:15
  • If you have answered your own question please post your own answer and √ accept it. If someone else answered your question for you please ✓ accept that answer. You can always add a comment if you feel it's appropriate Commented Jul 8 at 22:02

2 Answers 2

2

This looks to be pretty simple:

cat - << EOF |
<type:color>000000</type:color>
<type:color>FFFFFF</type:color>
EOF
sed 's/<type:color>/<type:color>#/'

Or just:

sed 's/<type:color>/&#/'

Where the & character is a placeholder for the text that matched.

To add that # only if it wasn't there already:

sed 's/\(<type:color>\)\([^#]\)/\1#\2/'

More legible if your sed supports -E for Extended regexps:

sed -E 's/(<type:color>)([^#])/\1#\2/'

Or:

sed -E 's/(<type:color>)#?/\1#/'
4
  • 2
    You don't need cat here; you could simply sed '...' << 'EOF' for that first line Commented Jul 8 at 19:43
  • 1
    In the replacement part of s/// the & character is a placeholder for the text that matched. You can write s/<type:color>/&#/ to save a little typing. Commented Jul 8 at 20:50
  • Hey thanks, I added some context and a thanks a couple of hours ago but it got removed for some reason, this worked for me. Commented Jul 9 at 0:06
  • you are taking advantage of the fact that : cmd 1 | (...newline...)cmd2_on_next_line is correct. But you can also add all the | additionnal_processing you want on the same line as the cat : cat - <<EOF | sed -e 's/\(<type:color>\)\([^#]\)/\1#\2/' Commented Jul 9 at 12:47
0

Assuming a well-formed XML document, like this:

<?xml version="1.0"?>
<root xmlns:type="uri://something/type">
  <type:color>000000</type:color>
  <type:color>FFFFFF</type:color>
</root>

... we may use e.g. xmlstarlet to update all values of all type:color nodes in the whole document, inserting a # character at the start of each:

xmlstarlet ed -u '//type:color' -x 'concat("#", text())' file

or, using longer names,

xmlstarlet edit \
    --update '//type:color' \
    --expr 'concat("#", text())' \
    file

Result:

<?xml version="1.0"?>
<root xmlns:type="uri://something/type">
  <type:color>#000000</type:color>
  <type:color>#FFFFFF</type:color>
</root>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .