is possible by simple way replace string (sed) limited inside 2 strings?
Example
I have xml feed contains many tags, including <DESCRIPTION> tag with special chars inside.
I need change special chars only inside this tag. I mean < to <, " to ", etc.
Source
<DESCRIPTION><p>Konvice s pokličkou smalt je vhodná ke každodennímu použití. Lze ji mýt v myčce na nádobí a je vhodná pro plynové, elektrické sporáky a indukci. Objem 2 l, v červené barvě s bílým puntíkem.</p><p> </p><p> </p></DESCRIPTION>Result
<DESCRIPTION><p>Konvice s pokličkou smalt je vhodná ke každodennímu použití. Lze ji mýt v myčce na nádobí a je vhodná pro plynové, elektrické sporáky a indukci. Objem 2 l, v červené barvě s bílým puntíkem.</p><p> </p><p> </p></DESCRIPTION>Or is another way to "repair" this xml?
Thank you.
UPDATE
It works, but for most of xml tags, even for xml head. :/
<?xml version="1.0" encoding="utf-8"?>
<SHOP><GENERATED>2021-02-05T14:15:02+01:00</GENERATED>
<SHOPITEM> <ITEM_ID>ABF644B</ITEM_ID> <PRODUCTNAME>LÁHEV NA VODU "BISFREE ECO" 550ML, HNĚDÁ</PRODUCTNAME> <DESCRIPTION>Láhev na vodu "Bisfree Eco". Díky barevné plastové láhvi na vodu lock budete mít o množství vypitých tekutin přehled. Malá velikost s objemem 550 ml s víčkem se totiž vleze do každé tašky či kabelky a vodu tak můžete mít stále při sobě. Láhev je vyrobená z Tritanu - lehký, odolný proti nárazům a kvalitní plast - neobsahuje BPA. Tritan je populární náhražka skla. Barva hnědá. Rozměry - 6,5×6,5×22 cm</DESCRIPTION> <URL> <IMGURL> <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE> <ORIGINAL_PRICE_VAT>199.00</ORIGINAL_PRICE_VAT> <PURCHASE_PRICE_VAT>164.46</PURCHASE_PRICE_VAT> <MANUFACTURER>LOCKNLOCK</MANUFACTURER> <CATEGORY>STOLOVÁNÍ | PŘÍPRAVA NÁPOJŮ | SPORTOVNÍ LAHVE</CATEGORY> <EAN>8803733138772</EAN> <ITEMGROUP_ID></ITEMGROUP_ID> <PRICE_VAT>199.00</PRICE_VAT>
</SHOPITEM>
<SHOPITEM> <ITEM_ID>ABF644G</ITEM_ID> <PRODUCTNAME>LÁHEV NA VODU "BISFREE ECO" 550ML, ZELENÁ</PRODUCTNAME> <DESCRIPTION>Láhev na vodu "Bisfree Eco". Díky barevné plastové láhvi na vodu lock budete mít o množství vypitých tekutin přehled. Malá velikost s objemem 550 ml s víčkem se totiž vleze do každé tašky či kabelky a vodu tak můžete mít stále při sobě. Láhev je vyrobená z Tritanu - lehký, odolný proti nárazům a kvalitní plast - neobsahuje BPA. Tritan je populární náhražka skla. Barva zelená. Rozměry - 6,5×6,5×22 cm</DESCRIPTION> <URL> <IMGURL> <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
...It should be.
<?xml version="1.0" encoding="utf-8"?>
<SHOP><GENERATED>2021-02-05T14:19:48+01:00</GENERATED>
<SHOPITEM> <ITEM_ID>ABF644B</ITEM_ID> <PRODUCTNAME>LÁHEV NA VODU "BISFREE ECO" 550ML, HNĚDÁ</PRODUCTNAME> <DESCRIPTION><p>Konvice s pokličkou smalt je vhodná ke každodennímu použití. Lze ji mýt v myčce na nádobí a je vhodná pro plynové, elektrické sporáky a indukci. Objem 2 l, v červené barvě s bílým puntíkem.</p><p> </p><p> </p></DESCRIPTION> <URL> <IMGURL> <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE> <ORIGINAL_PRICE_VAT>199.00</ORIGINAL_PRICE_VAT> <PURCHASE_PRICE_VAT>164.46</PURCHASE_PRICE_VAT> <MANUFACTURER>LOCKNLOCK</MANUFACTURER> <CATEGORY>STOLOVÁNÍ | PŘÍPRAVA NÁPOJŮ | SPORTOVNÍ LAHVE</CATEGORY> <EAN>8803733138772</EAN> <ITEMGROUP_ID></ITEMGROUP_ID> <PRICE_VAT>199.00</PRICE_VAT>
</SHOPITEM>
... 6 1 Answer
Try this, you need to install the recode package:
sudo apt install recodeMake a backup of the original file.
I have achieved this so far:
The code:
#!/bin/bash
# create a function to parse the files
f() { # get the original text between the tags inside DESCRIPTION decoded="$(sed -n '/<DESCRIPTION>/p;' "$1" | sed 's:<\([^>]*\)>::g' | sed 's/^[[:blank:]]*\|[[:blank:]]*$//g')" # get the encoded text from the decoded text encoded="$(echo "$decoded" | recode ..html | sed 's:<DESCRIPTION>\(.*\)</DESCRIPTION>:\1:')" # encode everything inside DESCRIPTION to temporal file awk '/DESCRIPTION/{"echo \""$0"\" | recode ..html" | getline $0;}1' "$1" > output.xml # replace the encoded with the decoded [[ ! -z "$encoded" ]] && sed -i "s/$encoded/$decoded/" output.xml # decode DESCRIPTION tags sed "s:<\([^;]*\)DESCRIPTION>:<\1DESCRIPTION>:g" output.xml >> result.xml
}
# create result file
> result.xml
# split the source file into <SHOPITEM> chunks
csplit --suffix-format="%d.FOO" file.xml '/<SHOPITEM>/' '{*}' 2>&1 > /dev/null
# loop over the "chunk" files
for i in *.FOO; do # apply the function to the "chunk" file f "$i" # remove "chunk" file rm "$i"
done
# remove temporal file
rm output.xmlThen:
$ cat result.xml<?xml version="1.0" encoding="utf-8"?>
<SHOP><GENERATED>2021-02-05T14:19:48+01:00</GENERATED>
<SHOPITEM> <ITEM_ID>ABF644B</ITEM_ID> <PRODUCTNAME>LÁHEV NA VODU "BISFREE ECO" 550ML, HNĚDÁ</PRODUCTNAME> <DESCRIPTION><p>Konvice s pokličkou smalt je vhodná ke každodennímu použití. Lze ji mýt v myčce na nádobí a je vhodná pro plynové, elektrické sporáky a indukci. Objem 2 l, v červené barvě s bílým puntíkem.</p><p> </p><p> </p></DESCRIPTION> <URL> <IMGURL> <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE> <ORIGINAL_PRICE_VAT>199.00</ORIGINAL_PRICE_VAT> <PURCHASE_PRICE_VAT>164.46</PURCHASE_PRICE_VAT> <MANUFACTURER>LOCKNLOCK</MANUFACTURER> <CATEGORY>STOLOVÁNÍ | PŘÍPRAVA NÁPOJŮ | SPORTOVNÍ LAHVE</CATEGORY> <EAN>8803733138772</EAN> <ITEMGROUP_ID></ITEMGROUP_ID> <PRICE_VAT>199.00</PRICE_VAT>
</SHOPITEM> 10