Issue
I am very new to this, so please bear with me. :( In a bash script for android where I am trying to replace a single stream of fonts.xml with another set of stream/line which are stored in another xml file, the line is:
<family name="sans-serif">
and what I am trying to replace it with is: (which is stored in another xml file)
<family name="sans-serif">
<font weight="100" style="normal">Thin.ttf</font>
<font weight="100" style="italic">ThinItalic.ttf</font>
<font weight="300" style="normal">Light.ttf</font>
<font weight="300" style="italic">LightItalic.ttf</font>
<font weight="400" style="normal">Regular.ttf</font>
<font weight="400" style="italic">Italic.ttf</font>
<font weight="500" style="normal">Medium.ttf</font>
<font weight="500" style="italic">MediumItalic.ttf</font>
<font weight="700" style="normal">Bold.ttf</font>
<font weight="700" style="italic">BoldItalic.ttf</font>
<font weight="900" style="normal">Black.ttf</font>
<font weight="900" style="italic">BlackItalic.ttf</font>
</family>
<family>
the goal is to use custom font as the first font as default via magisk module and Roboto as fallback. How can I replace the first stream with the expected set of stream with sed. I tried several basics sed but none seems to work!
Solution
If you really want to use sed for this, you can try this implementation that subtitutes out new lines (\n) for an unused character (%), performs the subtitution and then restores the new lines.
#!/bin/bash
multi_line_sed()
{
local find_str="$1"
local replace_str="$2"
local unused_char="%"
# 1. substitute out new lines (for stdin and function arguments)
# 2. perform replacement
# 3. restore new lines
find_str=$(printf "$find_str" | tr "\n" "$unused_char")
replace_str=$(printf "$replace_str" | tr "\n" "$unused_char")
tr "\n" "$unused_char" |
sed "s|${find_str}|${replace_str}|g" |
tr "$unused_char" "\n"
}
file="fonts.xml"
find_str="<family name=\"sans-serif\">"
replace_str="$(cat custom_font.xml)"
cat "$file" | multi_line_sed "$find_str" "$replace_str"
Answered By - Bromate