0

I need to perform search and replace using sed. starting from this sample text for example :

<TextView
                        android:textSize="20.0sp"
                        android:textStyle="bold"
                        android:textColor="@android:color/white"
                        android:layout_gravity="center"
                        android:textColor="@android:color/white"

i wanna replace all occurrences of android:textColor="@android:color/white" with android:textColor="#ffff5d"

I spent over 3 hours (yes so frustrating) without success the closer I get is

sed -i "s/"$android:textColor=\"@android:color/white\""\|"$android:textColor=\"#ff4000\""/g" path to file.xml

but it's far from right. as results is

androidwhite"|:textColor="#ff4000"/white"

what am I doing wrong?

2
  • 3
    Could you give a larger and more complete example of your XML document so that we can recommend a robust and safe way of parsing it with an XML parser?
    – Kusalananda
    Mar 8, 2021 at 7:56
  • Errors I have detected: You have a lone pipe sign there in the middle of your sed code, which probably shouldn't be there. You have an unquoted $android, which the shell probably expands to an empty string. And you didn't quote the slash in color/white. Suggestions: To quote the $, use single quotes, and to avoid having to quote slashes, use a different character to separate regular expression from substitution; for example sed 's|android:textColor="@android:color/white"|android:textColor="#ffff5d"|g'. And as @Kusalananda says, sed is normally not the right tool for processing XML. Mar 8, 2021 at 8:30

2 Answers 2

0

Using sed to edit XML files is almost never a good idea. If the XML file is formatted slightly different, your method will break.

If you had proper XML (and I guess you will need to have that anyways), you could use XML tools, e.g. xmlstarlet.

Proper xml means, you have at least:

  • The android namespace declared somewhere
  • The TextView tag gets closed (e.g. with />)
  • Attributes exist only once per tag (in your example, android:textColor is defined twice, which makes the XML invalid).

As you don't give a complete example of your XML document, I made it minimally valid like this:

<TextView               xmlns:android="http://schemas.android.com/apk/res/android"
                        android:textSize="20.0sp"
                        android:textStyle="bold"
                        android:textColor="@android:color/white"
                        android:layout_gravity="center"
/>

Now you can use xmlstarlet:

xmlstarlet ed -P -S \
  -N android="http://schemas.android.com/apk/res/android" \
  -u "//TextView/@android:textColor" \
  -v "#ffff5d" \
file.xml 

Output:

<?xml version="1.0"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:textSize="20.0sp"
    android:textStyle="bold"
    android:textColor="#ffff5d"
    android:layout_gravity="center"
/>
0

For my limited usage

sed 's|android:textColor="@android:color/white"|android:textColor="#ffff5d"|g'

works fine. I just edit some apk on the phone, so I don't even know if xmlstarlet binary exists for ARM 64 android.

You must log in to answer this question.

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