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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.