'RegEx search & replace & casefold, but only in certain lines

I have an XML file with lines like this:

<key>a_acute</key>
<string>a_acute.glif</string>

And I need to turn this into something like this:

<key>Aacute</key>
<string>a_acute.glif</string>

I.e. replace a letter followed by an underscore with the uppercase of the letter (leaving out the underscore), but only on lines starting with <key>. This is what I have so far:

sed '/^<key/s/\(.\)_/\1/'

This will drop the underscore on <key> lines. But I can't get it to casefold. I thought that putting a \U before the \1 would do the trick, but it doesn't. What am I doing wrong?



Solution 1:[1]

  1. As a general rule: don't use regular expressions to parse non-regular languages like XML.

  2. \U is a feature of GNU sed, not available by default on Mac OS X. You can install it from homebrew as gnu-sed or from macports as gsed.

  3. If you don't want to rely on outside tools, you can do it with perl like this (with -i the file is changed in-place):

    perl -i -pe 's/(?<=)(.)_/\U$1/' file.plist

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Glorfindel